Compare commits
1321 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9db88139d3 | |||
| a9068dbd0f | |||
| 06cad71050 | |||
| 3e52ee0c40 | |||
| 993e2f77a8 | |||
| da0431e69a | |||
| ccb66ff793 | |||
| cfb4a4cbaa | |||
| 92692d6939 | |||
| d9e220238d | |||
| 805adea8be | |||
| e6a4b0d8fb | |||
| 11e7b02653 | |||
| 55af05f8a3 | |||
| 93a98c256c | |||
| 3b18b981c5 | |||
| 1bf4253477 | |||
| 467d0873de | |||
| 77cea20b24 | |||
| e868887a29 | |||
| be04c5c896 | |||
| 369a9e9b1e | |||
| dd9b1b51ba | |||
| 28f0ef85cd | |||
| 367c5a1ec6 | |||
| 15061d46a9 | |||
| 102a6bbbf1 | |||
| eeaf1cdd72 | |||
| 10c87ba9b6 | |||
| 882d46d0b1 | |||
| d247f968fa | |||
| 29dbe8ed09 | |||
| c2275ad894 | |||
| 4e54d58318 | |||
| 4afaf438ea | |||
| d654045adc | |||
| b085606352 | |||
| d5893b8ee0 | |||
| 2f98fffc04 | |||
| 81c3bfd1ff | |||
| eacb1f7561 | |||
| 8d062e9649 | |||
| 61b359fb11 | |||
| 51f297a6fa | |||
| 5068f7999d | |||
| 5fce308c49 | |||
| 71cd1093ea | |||
| b4fa9ff479 | |||
| edc62bb346 | |||
| 0b6473f202 | |||
| 1f68b5b240 | |||
| f1ee97941e | |||
| 57ec0d82b6 | |||
| 770f50f9ba | |||
| 2af02291a6 | |||
| c9c4bca217 | |||
| 4ccaef4f22 | |||
| bc7ddd1f35 | |||
| 6b1b4f2253 | |||
| f6ea3147a7 | |||
| 107c598a46 | |||
| 7de10e0ff5 | |||
| 3514d539fa | |||
| 74739ca5b1 | |||
| b92312d0d2 | |||
| 923daaa8ba | |||
| 7e96eb2478 | |||
| 475bbf71ac | |||
| 80ac6ee67d | |||
| fcc0f6fa12 | |||
| f383337d78 | |||
| 019c780fcd | |||
| fdbf81c1cf | |||
| 9cb3991fec | |||
| f85ad98f06 | |||
| 039fac937d | |||
| c627c320bf | |||
| 1e7149a25a | |||
| 710b096765 | |||
| 72a4379087 | |||
| 1a48279d68 | |||
| bbe98da471 | |||
| bef22ea3d2 | |||
| d910e66cee | |||
| 735127be0b | |||
| 3ca11580ae | |||
| 24948a701d | |||
| 564abe331c | |||
| 250258dbb7 | |||
| e52d129d30 | |||
| e3c48f5dbd | |||
| a4ec5d2e92 | |||
| 1dfb366a1b | |||
| 4366fd508a | |||
| 2aee379b84 | |||
| 7e1b001ea4 | |||
| fc64737727 | |||
| bf79f4ea50 | |||
| 06cd041d4c | |||
| 862c94cbd1 | |||
| b1c7fda43c | |||
| 2cb204a14a | |||
| c1147d3e08 | |||
| 300113c21a | |||
| 0b18242922 | |||
| 8c4b0edc52 | |||
| 0a80486708 | |||
| 63573b4138 | |||
| b21ee18901 | |||
| ecf7b06d5a | |||
| 0059b61600 | |||
| 6dd853fc65 | |||
| 59ba6304fd | |||
| 6f1d4d616f | |||
| 736bcf95bb | |||
| 713c85179f | |||
| 95fff778c2 | |||
| bb5c8469c7 | |||
| 14331df196 | |||
| ffe7ccbf3b | |||
| 9b89fdcc07 | |||
| 0c5aa5d8bf | |||
| 2ff2cfe4e2 | |||
| 07ee30b7bb | |||
| 14d49836f8 | |||
| 25ab6e5f52 | |||
| 180ed68679 | |||
| 969244bbe9 | |||
| 66ea7851a6 | |||
| 3e71121c3f | |||
| 7057cd4439 | |||
| 78c6150219 | |||
| 68649e7ee1 | |||
| 93dd1e0e68 | |||
| 46cab0033d | |||
| a8cbfbff02 | |||
| 8519f75881 | |||
| 4d4b18ce31 | |||
| 99dba1777a | |||
| f87877d2fb | |||
| bfbb333379 | |||
| 3e51471614 | |||
| d659213d9b | |||
| 47a29edaf8 | |||
| daceb8d876 | |||
| 53ba1913c4 | |||
| ec3d146259 | |||
| 0b0c923519 | |||
| 84c818fbc6 | |||
| 3003110003 | |||
| 0b7a707179 | |||
| 47a5a4c536 | |||
| 0ea77b281a | |||
| 72de3aedfb | |||
| 92b9ca4b9e | |||
| 4fc4988238 | |||
| 3e8f68fe7f | |||
| b4dce6b70f | |||
| 59e57a1e84 | |||
| c6a0e6d4e5 | |||
| 46c9d5d788 | |||
| cad8c86a6b | |||
| f89163a501 | |||
| 4a48117c42 | |||
| 201427c9de | |||
| d155c8c68a | |||
| 0868963ef6 | |||
| 56636cf4e8 | |||
| e1ba890613 | |||
| 62f367a8ab | |||
| 856b80e2a1 | |||
| 9c14ddc07d | |||
| b089d456d7 | |||
| 12c91fbc60 | |||
| e39dbcd055 | |||
| d65ae4c854 | |||
| a5c16ad171 | |||
| bd27ca23be | |||
| 2486f856c3 | |||
| 3414416d01 | |||
| c8fbcc8541 | |||
| 6bb48f05a9 | |||
| f8f872641b | |||
| 6c9234df79 | |||
| 82157e991e | |||
| 020a114452 | |||
| c902672c60 | |||
| cf42c4e10b | |||
| bd094db1b4 | |||
| c85e2b60a4 | |||
| 9972e77adb | |||
| a1179f3018 | |||
| 0257de0ef2 | |||
| e60f695efb | |||
| dc2afed5c1 | |||
| c026a3d7fe | |||
| 316b58bd88 | |||
| 09c4277002 | |||
| 83eb5d2628 | |||
| b96e107a7c | |||
| 410217ac31 | |||
| 56f75cc342 | |||
| 47200ff1c8 | |||
| 3c5b618ff0 | |||
| 6a3bdba935 | |||
| cb77ac92d7 | |||
| 09dc9a129e | |||
| cd79e33f7c | |||
| ded2be133e | |||
| 066696686f | |||
| 90c24d0ff7 | |||
| 80deb78f25 | |||
| 7ec38c7be8 | |||
| 8d68a17dec | |||
| 8521b46ab2 | |||
| 3790ae7b65 | |||
| 37d616d5fb | |||
| b117fb3dbc | |||
| 57b6ff1af7 | |||
| fb71204859 | |||
| 5392fb7e34 | |||
| 83308c89e4 | |||
| 6dec17db73 | |||
| 1fa9bdb32f | |||
| 4dd43607b8 | |||
| daab6a0cde | |||
| efd7d6eadb | |||
| 9a9705a1bf | |||
| 9dcd216ac1 | |||
| 6e14118bcd | |||
| 3d31d5f112 | |||
| 8b6feb6b30 | |||
| f1976a7b99 | |||
| 089855bcd2 | |||
| 239add6be2 | |||
| 203d7025ad | |||
| 1141e9cd7d | |||
| f4296702e2 | |||
| 3583d5b59d | |||
| 4934dba5ea | |||
| e651a540d7 | |||
| 8bcf0a8717 | |||
| e342bd876c | |||
| 2b453aea6f | |||
| 2433281aa5 | |||
| 99f1ac8b79 | |||
| c9508a7966 | |||
| 75bb52802e | |||
| 80d3424855 | |||
| caed010c3d | |||
| 84b503a443 | |||
| 39c66d052f | |||
| 5f0da1b2de | |||
| 76edfcf670 | |||
| 5d02531baa | |||
| a0370be23f | |||
| f79ec9bdbd | |||
| 44f26b478d | |||
| 777c00e8d4 | |||
| 7754845c7c | |||
| 9a64ca9b84 | |||
| 1e3fa1a1e9 | |||
| 5e728c73a1 | |||
| 74d5d437d5 | |||
| af6b21edb0 | |||
| 4bbda3998f | |||
| de3184b24a | |||
| 219badd6f2 | |||
| 77ea7d4e41 | |||
| 431470e035 | |||
| 1ca9533e61 | |||
| 7db86eedff | |||
| d8e840bafd | |||
| e861a7c0a9 | |||
| 42af194434 | |||
| 643952493a | |||
| 5653f343a3 | |||
| 1b5cf5e044 | |||
| ffc621cf29 | |||
| 4082f1da22 | |||
| 7c29fd4757 | |||
| e1635a9b48 | |||
| f58a3f2f9a | |||
| 817f8ce411 | |||
| f1dc5da446 | |||
| 4f91b33757 | |||
| 031bc1e3bd | |||
| 8b8b932213 | |||
| 9704a7b176 | |||
| 716bb97084 | |||
| 815e2d6583 | |||
| dbcab937da | |||
| 3e0d22db7c | |||
| 01c3a1070d | |||
| 5205218f1a | |||
| 84e9d74314 | |||
| 464c4b0d3c | |||
| a96f96e2d4 | |||
| 0fe302f9e8 | |||
| 7ad12aba70 | |||
| d9e9515cf5 | |||
| 91d27eb358 | |||
| 890555235e | |||
| f0c6bcdbad | |||
| 115aef46f3 | |||
| 53209a79d1 | |||
| e1603a0242 | |||
| 552063ef57 | |||
| 6483bbc18e | |||
| 70c9b7c583 | |||
| 3c86356e3b | |||
| 5a09a9b34a | |||
| 28fba7f066 | |||
| ac79179400 | |||
| e91888a79b | |||
| 1a5b1e9086 | |||
| 0fa516df77 | |||
| 25b028a5fd | |||
| f4ddcdb9de | |||
| 2374e40b4e | |||
| cae2da8eba | |||
| e313b49839 | |||
| 80e8c21af7 | |||
| 9c0032b3c1 | |||
| 624fce5e4d | |||
| 814974aaa8 | |||
| 1810107998 | |||
| 045011b168 | |||
| 67a663131e | |||
| 6853cbc89f | |||
| cb9794ccdb | |||
| 9b3f5a15d0 | |||
| 2b0caf0346 | |||
| 62ee471f89 | |||
| 19a77111f6 | |||
| e6f7e461e4 | |||
| 56cab3f2c8 | |||
| adf53e32cd | |||
| 77bcb15656 | |||
| ef7fe69e19 | |||
| 67a7fab655 | |||
| b81e4cee2d | |||
| c93aeba53c | |||
| c057f231a0 | |||
| 5eaaf7369c | |||
| 0bdae5e4c4 | |||
| 37118daaf9 | |||
| a9acb42b1e | |||
| b3cf456fae | |||
| 7dd70c12d2 | |||
| f2b4b14a53 | |||
| 11b99248a9 | |||
| 8600f159b0 | |||
| c03f4d202f | |||
| 88914d3493 | |||
| a2a9dc9efd | |||
| 4cdeeb0b22 | |||
| 5ca816b0c4 | |||
| 529597d3c1 | |||
| 08f4ed81e5 | |||
| d6ce28f954 | |||
| 16be3f4902 | |||
| 1808cbf129 | |||
| 6969c52f82 | |||
| 09bf36a323 | |||
| 1b5ff23093 | |||
| 73ab8e8a7f | |||
| 0995a924dc | |||
| 311d3aafac | |||
| d948f8c69e | |||
| 368d0d1e83 | |||
| 18db706c89 | |||
| 020889ad3c | |||
| 76a47d856c | |||
| 4225daa29f | |||
| 3c874d9555 | |||
| 839c6d85a3 | |||
| fbd772e8cd | |||
| 92ec068fe4 | |||
| 68b4a0b5c7 | |||
| 650928ad15 | |||
| 4e79b8d8d7 | |||
| 67a48e2ee6 | |||
| 5459cf6a60 | |||
| 600ab740ae | |||
| 5f8d394346 | |||
| 6fb47b1d50 | |||
| 780fbaaad8 | |||
| 63edd565d1 | |||
| 2bca640ffa | |||
| cbb73b46a7 | |||
| e88a680e6b | |||
| 8921bc2734 | |||
| df1c520161 | |||
| 861794f576 | |||
| d0411a285f | |||
| cf502073f4 | |||
| 0f0046ca9d | |||
| b7701969ed | |||
| 918bd4270a | |||
| 3f56f0775e | |||
| 56b6f4c1b2 | |||
| ecd518e31e | |||
| a7e3e9ec2a | |||
| 008e72d316 | |||
| 1de09a51c9 | |||
| 106dc7874a | |||
| bf183224c7 | |||
| 4a2b39754f | |||
| df9fa2b101 | |||
| 3847fe71c0 | |||
| 4a91bb39cc | |||
| a81d66c124 | |||
| dab5a33b3f | |||
| 016a947428 | |||
| 79748cf356 | |||
| 85bf65876e | |||
| 8c2e36a02c | |||
| f2fcf48b5d | |||
| f52348bc1a | |||
| 64d03a8212 | |||
| 811a3eda65 | |||
| 9e71285c78 | |||
| d3bf022de7 | |||
| 4bd8a0e020 | |||
| 3ddce5fb90 | |||
| 52c1236f4e | |||
| d258f3a3c0 | |||
| 143f106f7d | |||
| 29b94ff6a2 | |||
| 0682ed07d3 | |||
| e518020aa4 | |||
| b67fcaed89 | |||
| 0a55da08fe | |||
| 7b7085742f | |||
| 487daef0d6 | |||
| f9533a6843 | |||
| bc96478730 | |||
| c0aeae7dd1 | |||
| 7d90895a38 | |||
| dd74f95007 | |||
| 465409982d | |||
| 04d832ce3d | |||
| 9f8a9efc4b | |||
| 6b26f84cf9 | |||
| a70323051f | |||
| 6996dc4f8a | |||
| 77e5889721 | |||
| e9d378a484 | |||
| d17e10419d | |||
| 392472e328 | |||
| 32e5e85a08 | |||
| 3065b2d394 | |||
| 594d5ce981 | |||
| f95c0026eb | |||
| f5d013dc48 | |||
| eb102a0d36 | |||
| 570cd821e3 | |||
| b4a5ddf4dc | |||
| c28fe1ef3b | |||
| a20d2ed496 | |||
| 965059d45c | |||
| 3f38f26761 | |||
| 223002d905 | |||
| 35457cb9ac | |||
| 39501e0b6c | |||
| cb8a813820 | |||
| 624a45bfa3 | |||
| 793cb090c4 | |||
| f099ffd1a5 | |||
| 49aad9e6bd | |||
| 465c5471a0 | |||
| 9524019f0b | |||
| b12951579b | |||
| 1d2391454e | |||
| f15ce9f06e | |||
| e5e7e4687d | |||
| 75bfe9b646 | |||
| 1144077591 | |||
| 8ea54a435f | |||
| 42b3c0c596 | |||
| 7ed707c67b | |||
| 1bb5051da7 | |||
| 95226fa3a8 | |||
| 23d64d7acc | |||
| 55fc5d4064 | |||
| b20ccd2905 | |||
| b802a02442 | |||
| 987d47a43d | |||
| 19241bce05 | |||
| e7f9eadd1e | |||
| acc28bb0ed | |||
| 1dd5758ff7 | |||
| 05778c7853 | |||
| ca700dca54 | |||
| fa4a8e6e28 | |||
| 90c22ee298 | |||
| 10986247e3 | |||
| 559c75e567 | |||
| dc432e7139 | |||
| 2e3dd4761e | |||
| 2b2d482aac | |||
| 1ef39d6ef8 | |||
| 3260c52a35 | |||
| ec54b30aa4 | |||
| 804fd22cf2 | |||
| b58ab630a6 | |||
| b27065d834 | |||
| e917ce1579 | |||
| 3ddb75d072 | |||
| 3724aed861 | |||
| 4d3ee33232 | |||
| 3910ec03e1 | |||
| b08b9a3c77 | |||
| f787c85ddc | |||
| 201f9895ed | |||
| 33693f8486 | |||
| 0f9d930de3 | |||
| e20198b86b | |||
| 2959fea562 | |||
| 7e90f3e8ea | |||
| 9af0a72bfc | |||
| f570a29c5c | |||
| 26e8951512 | |||
| 7ad5f1a53a | |||
| a5e8f44514 | |||
| cb290f429d | |||
| 9f9c6d2c79 | |||
| aa9d9140d0 | |||
| f4dca63e79 | |||
| 1c027a87d7 | |||
| 0916af5577 | |||
| d4816f7159 | |||
| 4e54ba0682 | |||
| 396d8b304f | |||
| c2afea1cb8 | |||
| d7d330966d | |||
| b9377d7251 | |||
| d3846f47f8 | |||
| 9c2a7d275b | |||
| ec5be914c9 | |||
| 16e0d2179a | |||
| 869ae04a45 | |||
| 80f923b96c | |||
| ef8b638460 | |||
| de974743c9 | |||
| 5f97813937 | |||
| 3a5af60c3f | |||
| c1bad5bcf6 | |||
| 611a5ff463 | |||
| dbd453d0a6 | |||
| 0ae570f73d | |||
| d80d963951 | |||
| af005c6a31 | |||
| 707e24b981 | |||
| 58249c8b14 | |||
| b5765f2fcf | |||
| 10caf24da8 | |||
| 5435fec0e5 | |||
| eaf843d6c4 | |||
| 0716b8596d | |||
| b0805684cc | |||
| b14a373512 | |||
| f0872d459e | |||
| ab3a23346b | |||
| cf06cc036d | |||
| 0b410a596b | |||
| 9799ef78e6 | |||
| 73fb28f6d0 | |||
| a758cdf573 | |||
| 9d65034701 | |||
| 11df32128f | |||
| 22468165b6 | |||
| 5c045ed61c | |||
| e2684acebe | |||
| c48f202bdd | |||
| 89ba8006f4 | |||
| e57868c1c6 | |||
| 38cea20397 | |||
| 2f669c1ac6 | |||
| d5e329e4c7 | |||
| 34bb809cc4 | |||
| c2cd84dbca | |||
| 0edc77694f | |||
| 8ac0f31915 | |||
| 4ce4e7c0fd | |||
| 69f6fa5693 | |||
| edbad6e498 | |||
| f5a31b7f4f | |||
| c68a422c44 | |||
| 3d06ddda0d | |||
| f890d03ef3 | |||
| 9ecfc50b91 | |||
| 78af39e06f | |||
| 645c602ce2 | |||
| a6aab0c6d0 | |||
| 592a0d508c | |||
| 7d5bcba0d5 | |||
| 594facc9a0 | |||
| e2d8a38928 | |||
| b6969b9817 | |||
| cd406905a8 | |||
| be3e25ce00 | |||
| e4d371d2e8 | |||
| 0244b031cf | |||
| 8fac597977 | |||
| 6738d6caba | |||
| 30c92ba536 | |||
| cff0e482eb | |||
| 47fc94d842 | |||
| 60ca873f6c | |||
| c5bba25f7e | |||
| a55349b5af | |||
| d1b41732b5 | |||
| db6e509b4a | |||
| 252e7dd3de | |||
| b2838fdca8 | |||
| 0ef6f64ab2 | |||
| 4e7720631b | |||
| c4a211ddd3 | |||
| 6e3206d31d | |||
| 1dfe0cb135 | |||
| f53574d1c6 | |||
| 5d4aace149 | |||
| 961c3951e6 | |||
| dcde28a213 | |||
| bc386fd56a | |||
| 636d866a40 | |||
| 36c4a83005 | |||
| 2649d44ed4 | |||
| e057ae26fd | |||
| 8754a7ee0c | |||
| 193bea48f6 | |||
| 685e039254 | |||
| 6a72e5feb6 | |||
| f6c559ca0a | |||
| 03584e81fb | |||
| d7bc639fc6 | |||
| 5b846b46a4 | |||
| 07023c0634 | |||
| 756c176f53 | |||
| dabe1aafca | |||
| 422c7cfef4 | |||
| 37a2bfde40 | |||
| 1ea7732f00 | |||
| 25bfbdee5e | |||
| 9585feebb8 | |||
| 5921d3cd95 | |||
| e8d1d7cf00 | |||
| 0479d3682c | |||
| b1c996ad2e | |||
| 5985c790d0 | |||
| f5bb7a2bc6 | |||
| 0cb3d901d8 | |||
| f930deea97 | |||
| 8d855e9e20 | |||
| 0df81a3dfa | |||
| b662046e19 | |||
| aedb671f1b | |||
| aba2b94d5c | |||
| 1cd456419a | |||
| 726c05134c | |||
| 8945c5ca33 | |||
| 24a2928e03 | |||
| d991d97332 | |||
| 2b35adf1f8 | |||
| d4d56cbc91 | |||
| 8210f4d82a | |||
| b8e32de9c8 | |||
| 607a2cc927 | |||
| 581739c5e5 | |||
| 608ecae96e | |||
| 52a0a5a4f4 | |||
| f170fe9c0f | |||
| 223d288cff | |||
| f9841836f9 | |||
| 4e9d9d0b7a | |||
| 268d20215e | |||
| 3a71acedeb | |||
| 09f4a16b24 | |||
| 61effb412e | |||
| 4b75dd3c03 | |||
| 456bd50c46 | |||
| f1cd22e0f8 | |||
| 4b57fe95f4 | |||
| 310287347a | |||
| 5b497df6e3 | |||
| 8e64beb962 | |||
| 4cdc6dab13 | |||
| 61569206a1 | |||
| 040ae224e5 | |||
| 9980daedc4 | |||
| 81ec3ad929 | |||
| 962772547d | |||
| 3341f2399b | |||
| a5ec8dcc36 | |||
| 66f9824509 | |||
| 348ccaf564 | |||
| 41aa89541c | |||
| 8a476a618b | |||
| 27ba4fcdbe | |||
| 4fd57c08e5 | |||
| 95b4be91eb | |||
| 8d2eeda1b3 | |||
| c48d82729c | |||
| a2fb35c9c5 | |||
| 3154df9b77 | |||
| 47fbbd2230 | |||
| aa01feda37 | |||
| a8323e599a | |||
| 62e8e445b9 | |||
| ea7577eb8f | |||
| 8c4dfd3470 | |||
| 019f6da484 | |||
| ce63e80e96 | |||
| 91fc845782 | |||
| dbd59da228 | |||
| 1f963dc243 | |||
| e0c25f0672 | |||
| cbdd1d4a9a | |||
| 273c3098fc | |||
| d3590828a7 | |||
| dd66c4427a | |||
| 2cb38161a8 | |||
| 2660c46a24 | |||
| 3ae9f03fe1 | |||
| 0ed2145239 | |||
| 546bf507ab | |||
| b13c713888 | |||
| 29aa9d83a7 | |||
| a7537857db | |||
| af3ac58d23 | |||
| fb453010c4 | |||
| 607866fb4a | |||
| aa5e95f28a | |||
| df158b4411 | |||
| 57bfbd67ad | |||
| 4d3bfb86c9 | |||
| 944a84bc0a | |||
| fd942bcf5a | |||
| 3456243248 | |||
| 7731929803 | |||
| ee3e6061f0 | |||
| b784427dbd | |||
| e439bfa3d9 | |||
| f4b3f09bb0 | |||
| cd354d6634 | |||
| 5562af5751 | |||
| 4896b906d4 | |||
| 2e53f21b7d | |||
| 97f11587b0 | |||
| 07da4182ab | |||
| 01ab6d41ea | |||
| f7208c1e81 | |||
| 56d12b7105 | |||
| 1e4a3631cc | |||
| c176287626 | |||
| e81e433f1e | |||
| e514305d5e | |||
| 0170a13ab4 | |||
| daa650686d | |||
| de0872c616 | |||
| a50b572e6e | |||
| f65080fb4b | |||
| b9bac72399 | |||
| 3dc5351cb4 | |||
| d10259eed1 | |||
| 42cb3d8799 | |||
| d256906e89 | |||
| e853c4c7e2 | |||
| 2ad903b713 | |||
| 32943f0a7a | |||
| 9a08f260ef | |||
| 4b65890eca | |||
| a6c2909603 | |||
| 06c90dd2e6 | |||
| a5ea4c5332 | |||
| f2fe9bd17e | |||
| 38f585626d | |||
| cac34c9f5a | |||
| 985de85cad | |||
| e6970bd97a | |||
| a392cfbe78 | |||
| b3a9a398dc | |||
| d302ccb027 | |||
| 79a7d3e4cc | |||
| aca25db4c9 | |||
| 428c90336d | |||
| 043303d1d7 | |||
| c600b54122 | |||
| 62d58ee68e | |||
| d8f8c7e49a | |||
| d1b10a4109 | |||
| d7c626da34 | |||
| 48b21d9656 | |||
| f212c3c7b3 | |||
| 75980fabbf | |||
| 5eb7f30342 | |||
| a95e58f482 | |||
| 082db86c77 | |||
| 05415e6588 | |||
| 15ecb156d4 | |||
| 9736ea127e | |||
| dfbfa103ec | |||
| 2e54ebc370 | |||
| 0724220b72 | |||
| e2055a8251 | |||
| 88e689b996 | |||
| e12bb46487 | |||
| 73f0454a44 | |||
| bcf9e0aff2 | |||
| a0f0bc1e07 | |||
| 16521bee18 | |||
| a899468623 | |||
| a8d2c285e0 | |||
| a2deab209f | |||
| c417dedd8c | |||
| 2038645410 | |||
| 4936c5bf4d | |||
| f6e8475fc0 | |||
| 9b59bb8c1f | |||
| 6fc19c33fc | |||
| b5a2045b3d | |||
| 815b733659 | |||
| b6a22759e0 | |||
| 0b08676d8c | |||
| d4da62ff92 | |||
| dce814e616 | |||
| 241de0adc3 | |||
| 0ea2f46895 | |||
| f6907796af | |||
| d3f9b881f5 | |||
| a2ac89d215 | |||
| 02aa34a40e | |||
| 421a20be05 | |||
| 562852decd | |||
| 9704b4db41 | |||
| 5b4e678952 | |||
| f8068d6b95 | |||
| 111d0ada77 | |||
| a51ddf27d4 | |||
| 789c6ede3c | |||
| 4646d343f6 | |||
| 055629b901 | |||
| c2f9aae59f | |||
| c38886fc70 | |||
| 6b5ce463ae | |||
| e96ada6593 | |||
| f9f1d61069 | |||
| 9a2aee8fbc | |||
| 9a672c7329 | |||
| 4f8e82198a | |||
| f5e89691d4 | |||
| 86f8818f75 | |||
| 962e478345 | |||
| 636f0bd5f6 | |||
| 325b3cedd4 | |||
| c50fe660e0 | |||
| de0d1d84ec | |||
| 06a0dcb472 | |||
| ad0e9d09d4 | |||
| 90c6689438 | |||
| 8fa5961b27 | |||
| 8cb2dd56b9 | |||
| a25f969d2d | |||
| 2515cfc4d4 | |||
| e6c6be8827 | |||
| d7892547c3 | |||
| 19c63b2412 | |||
| fa9bb0c3ca | |||
| 910948236c | |||
| 95bdb18675 | |||
| 49667756cb | |||
| 2eff25fb6a | |||
| 3560655bc6 | |||
| ce5ec17fcd | |||
| 8acceb8579 | |||
| f79c178354 | |||
| 49e21e3a8d | |||
| 4ffb6b22a8 | |||
| 6f94c8dcbe | |||
| 0d67ef61e7 | |||
| 11f93c43ae | |||
| dae618c4bb | |||
| c546de11e5 | |||
| a7a5e0aa70 | |||
| 01be6f53fe | |||
| 8bad0490c3 | |||
| 6410db445d | |||
| 37234b42cc | |||
| 3c0983f60f | |||
| af2e791dc3 | |||
| 2a38296b67 | |||
| b644f217d6 | |||
| cf51a10163 | |||
| bf18ab507c | |||
| 5afad2b6c8 | |||
| 722355e373 | |||
| fecdc35716 | |||
| 317676b98b | |||
| 6b74b9ae3f | |||
| baddac4d4c | |||
| 53dfc9e005 | |||
| 1e4a158fb4 | |||
| 08bd9b2907 | |||
| d6ada83292 | |||
| ab3b74fef4 | |||
| 2c5ce1a401 | |||
| 16e114ede4 | |||
| b1f539a5e5 | |||
| 9acd1e0a62 | |||
| c03aeddd19 | |||
| 1f29d3705d | |||
| 719ce7458c | |||
| abf2a60062 | |||
| 3c0eea3f26 | |||
| 574b11fc1b | |||
| 829dd22b6c | |||
| ba2193e39a | |||
| 6336859884 | |||
| 00cd0a4e67 | |||
| 15a76588d6 | |||
| 5075ed8045 | |||
| ab04cdafc3 | |||
| 093e1cb8e4 | |||
| 9c89936b69 | |||
| 63b5ea43c9 | |||
| 575100ab75 | |||
| d8b7c905a6 | |||
| b7d1915698 | |||
| bd8f5021f5 | |||
| 538e43dfa2 | |||
| 66a5a01733 | |||
| 26dcd874de | |||
| e61792e180 | |||
| 0fc0fbfcff | |||
| f4b76731c4 | |||
| bda7f19bc4 | |||
| c8ee86a306 | |||
| aa204c02fb | |||
| 4ca934115b | |||
| 283d9711e5 | |||
| 76ccff5b66 | |||
| a8094a6ec4 | |||
| 9c42853e1c | |||
| 1f23d67e4d | |||
| 3a7d35f220 | |||
| ed369ce3b8 | |||
| 2751c2cb43 | |||
| 5c437d385a | |||
| 07ad36c9d2 | |||
| 8ef2221595 | |||
| e9caf6e420 | |||
| 43a383bd68 | |||
| 1bb3f61a84 | |||
| a57b1bbfa6 | |||
| 309b357920 | |||
| ac13f9a177 | |||
| 805e0d5fd1 | |||
| 2226a4e58d | |||
| ceb308e21d | |||
| f7b2205e92 | |||
| 60f393ea20 | |||
| edd1ecd3d7 | |||
| 8d54d0c251 | |||
| 19cd9c4766 | |||
| ad308476bd | |||
| be14247f0e | |||
| 002c6f54d5 | |||
| 612a83d020 | |||
| cc6acc6bb0 | |||
| 3b071e27a0 | |||
| 540dc00882 | |||
| 4de74e13fb | |||
| c308aa725e | |||
| 64bae37fe1 | |||
| f1471cd5f7 | |||
| e63dc81a22 | |||
| 3e01b29a0d | |||
| 0df98e654c | |||
| 056ee611fd | |||
| 5d8c72397f | |||
| 486f8cf81a | |||
| d3107ef14b | |||
| 501b7f1f7e | |||
| f4a9ec312c | |||
| d652fa96fb | |||
| a2205b8fab | |||
| 8a53557d7d | |||
| af9428ed10 | |||
| 250336787e | |||
| 2702329dda | |||
| 3cc7478097 | |||
| 99dd2a7520 | |||
| 811829c9b5 | |||
| 04889ca0c2 | |||
| cfcf63be3a | |||
| 9e50bea3e6 | |||
| bf4b276286 | |||
| 9b378cdf85 | |||
| cfbefff7c7 | |||
| 0cb19bfa2b | |||
| feadffbc7b | |||
| d72811fe49 | |||
| 96c92e083a | |||
| b0740da8c4 | |||
| 83e36d1d07 | |||
| d421ad766a | |||
| 486d2c3027 | |||
| fefe378467 | |||
| d616ef7269 | |||
| ee67cada6f | |||
| ce65f31188 | |||
| 049afdbdf0 | |||
| 8b680bb3b6 | |||
| 317368df00 | |||
| 8428a71e7b | |||
| 89209d885b | |||
| ef7ebb34b8 | |||
| 87497e65c5 | |||
| 5ea143c734 | |||
| 41c00b59e2 | |||
| 0bc40f667a | |||
| 2091c7a1c7 | |||
| aa807e7dca | |||
| 631fa6d9ca | |||
| 1f07c5c769 | |||
| 5165ce4098 | |||
| e70bea3edb | |||
| cb3ccba715 | |||
| 5ae42f335c | |||
| 7211b9c3d5 | |||
| 700b9a6483 | |||
| f0cd1b890a | |||
| d83a06c0c3 | |||
| bb7ec57c23 | |||
| 980e17ea82 | |||
| 3c42ae7c06 | |||
| 44d26e560f | |||
| 9a584bdb4b | |||
| e977c2b2d8 | |||
| 2e91fbbf48 | |||
| 082f7f3e3a | |||
| 21bbe861a5 | |||
| 3ca8c9a561 | |||
| c6005f0dac | |||
| d5ab1780ab | |||
| 5795765011 | |||
| 337ca536f0 | |||
| c16a9a31d7 | |||
| cc4b65dfa8 | |||
| dd835f744c | |||
| f21047b44e | |||
| 28e50efbef | |||
| f5eb7b6713 | |||
| 15ad3d4144 | |||
| a799e2602e | |||
| e748ed903d | |||
| 47bcc75d71 | |||
| de3aa1ae04 | |||
| 27c9f9dbb3 | |||
| 90ec9da165 | |||
| ce684e0108 | |||
| 094aee795f | |||
| 1dcd7a42b1 | |||
| b6260d6a70 | |||
| 91d690e502 | |||
| 95d973258c | |||
| cf0bfb9d11 | |||
| df39576937 | |||
| e6cee5014a | |||
| c1ee6f6383 | |||
| 50a575c952 | |||
| 6c97efdae9 | |||
| d820388726 | |||
| 354269134a | |||
| 6ef1671e23 | |||
| b28f6f307f | |||
| 64b30e639c | |||
| 6055da9ab6 | |||
| 6e36a72117 | |||
| 4f8cacb6bb | |||
| 311e4d2e1d | |||
| 60ced905aa | |||
| bfe01b3aeb | |||
| 3b984994b8 | |||
| 17d12747a8 | |||
| 29cbd7344e | |||
| b2910a9ff7 | |||
| daada72738 | |||
| f618da03b0 | |||
| 994a61b23f | |||
| d83ddb7f69 | |||
| 3759698b55 | |||
| 8b4949d1fd | |||
| 25c43dac30 | |||
| 28a4eccb48 | |||
| e65799ab28 | |||
| c063fe1a6f | |||
| 2f1908c0fe | |||
| 69898aee7a | |||
| 745e92baec | |||
| cb171eab7a | |||
| 35ea34acc3 | |||
| fee4fccf1b | |||
| 7fddd47f72 | |||
| 170647e000 | |||
| 123abffe4f | |||
| c911961b09 | |||
| 03a445a74a | |||
| 7bb722ae35 | |||
| fc69abc703 | |||
| 23847c14c7 | |||
| c4368dc065 | |||
| dfd8ebdf2a | |||
| 6c304ce11c | |||
| 20c386bac4 | |||
| 7d7e447c3d | |||
| df101c0356 | |||
| 16b5f241de | |||
| df072efeb1 | |||
| e88555600a | |||
| bc1554306b | |||
| a301b0ac25 | |||
| 25bce09a12 | |||
| ba0f3429f7 | |||
| 858a39687d | |||
| ce4891f5c2 | |||
| 21618dde89 | |||
| 8555e39312 | |||
| e0e4031f68 | |||
| e36818588b | |||
| 74ac16a3ad | |||
| 4def0472ed | |||
| d3b43b6f9c | |||
| bda8a294b6 | |||
| e3073a442f | |||
| e682391071 | |||
| 5e1d6d912c | |||
| bfcfd7311a | |||
| fe5e749dfc | |||
| f07a2af37c | |||
| 0062a95fed | |||
| 0226f26fc6 | |||
| 1ecc7a08db | |||
| 35f86b5f09 | |||
| 04112294b3 | |||
| 0ceaa7466b | |||
| a0a6db72ff | |||
| 199505c28b | |||
| 0fa5e225b0 | |||
| 044848b35d | |||
| 1c34bf0180 | |||
| 8bb98b06de | |||
| fafee79e70 | |||
| a3875d16d1 | |||
| 77f206907b | |||
| 810bf5f8b7 | |||
| e02c1b8b67 | |||
| a67cacfdbe | |||
| c2bb10e13c | |||
| a7e6eafbac | |||
| 86d6fd80b3 | |||
| f7571ecb81 | |||
| b964b3f563 | |||
| 773f4d0fc0 | |||
| 8b57285cc1 | |||
| 0ded16368b | |||
| 716a006d2b | |||
| 4e91fb6cc7 | |||
| 74db2d9120 | |||
| 10d1f08e23 | |||
| 611aa5f994 | |||
| 43de2697b3 | |||
| 91fbf65bbf | |||
| 6c2c51d3d5 | |||
| 00c79814f4 | |||
| b17cbaf52c | |||
| 5eaf51ad77 | |||
| e9cae5c5d6 | |||
| 07295f7953 | |||
| 036bab9e21 | |||
| a2eb94fd1c | |||
| baca52bda8 | |||
| fb420f6330 | |||
| ed1fa52e8a | |||
| 7137646f44 | |||
| 10e6ad65a4 | |||
| 2451236800 | |||
| 8bab44fcbc | |||
| ef5351655c | |||
| d641143c50 | |||
| 0b3016522b | |||
| 4ce55c6175 | |||
| 11964eed4f | |||
| 1416c62968 | |||
| 861545f333 | |||
| c8ffae5242 | |||
| 870aec0318 | |||
| cba4b90473 | |||
| 9434376e11 | |||
| caa66f419a | |||
| 92b22201f6 | |||
| f688bd1efe | |||
| 8a1841c238 | |||
| 83c02ade0d | |||
| cb803eff21 | |||
| cbcf638b34 | |||
| fed0c20efd | |||
| b1b5e12fa4 | |||
| bf8182e9ed | |||
| e0b498898d | |||
| 828417286b | |||
| 0f1f11b01a | |||
| 17df46078f | |||
| 988acc9cf9 | |||
| 1d200f5e4f | |||
| 6e64b59a07 | |||
| 7e375c5162 | |||
| 233ff4faf1 | |||
| 59130c5163 | |||
| c18b476889 | |||
| f586f6453b | |||
| 016c25940a | |||
| 64e2391d02 | |||
| 8db73414b3 | |||
| ba6778494f | |||
| d19df65b7a | |||
| dfd9d9a7a8 | |||
| 372a951dee | |||
| ccd2746668 | |||
| a6a5ddfca9 | |||
| 463e95e1cb | |||
| 0dd99cd1cf | |||
| 1919c0b25d | |||
| 76115f17d0 | |||
| 1e19da4709 | |||
| 739f2f4318 | |||
| e469851b25 | |||
| 79c8fec75a | |||
| 016f967cce | |||
| 7901088307 | |||
| dd7d473d49 | |||
| 1ecd2f5164 | |||
| 841d58be57 | |||
| 58e96b4a07 | |||
| b6d19b4c8e | |||
| 38d37ad6ff | |||
| 2b4030ce0e | |||
| c03ae7778d | |||
| 905ec1d14f | |||
| 0cb0a17479 | |||
| 8c7cf3ae29 | |||
| 5acdc18ced | |||
| 191dcde3dc | |||
| 102c33be71 | |||
| be9f165796 | |||
| 7f926c1346 | |||
| 80254362a0 | |||
| e9c2d13e0c | |||
| e747066b32 | |||
| 64cf838838 | |||
| 6f3e2fb2f0 | |||
| 7f18ae6d6f | |||
| b906c24816 | |||
| 476c3387cc | |||
| ad004fa062 | |||
| 6e96acde8a | |||
| 4feb1eacf1 | |||
| 9ba0674087 | |||
| 77f1b1b726 | |||
| f8967bc0b6 | |||
| 863ba244c3 | |||
| 47ab424f70 | |||
| bae3e6b789 | |||
| 093b05b784 | |||
| 3948b72c22 | |||
| 093fa0578c | |||
| dcd1acab69 | |||
| 5dbcb3dd65 | |||
| 2f218a06f4 | |||
| 6c8f3298fa | |||
| a4000ce977 | |||
| 7ba40528e4 | |||
| 7fd00ce8ae | |||
| c2dec7b40b | |||
| 4a3919e899 | |||
| 4da96c27a3 | |||
| 72b785338b | |||
| 711b13383f | |||
| 8253aee359 | |||
| 07fa06c4dc | |||
| 184487e37e | |||
| 05ade551f4 | |||
| 6aee46151c | |||
| 550b50149c | |||
| ba121aef4a | |||
| 40a9d41e0b | |||
| 84ba7a178c | |||
| e11b310efd | |||
| 232f325351 | |||
| b56f7e9e94 | |||
| 68b6032dbb | |||
| 364e652e59 | |||
| 29f32d10ae | |||
| aba74b7d52 | |||
| 1616e26c94 | |||
| 86042cc1f4 | |||
| fa2eeecb0d | |||
| 509934b9d5 | |||
| bb90fdf022 | |||
| c24aadccfc | |||
| cbcb75cdb5 | |||
| 1e9af7be3b | |||
| 7c678fd174 | |||
| 982d3f1aed | |||
| e7e4071365 | |||
| 136e94ab83 | |||
| 33193fc495 | |||
| 4f6485c841 | |||
| e0390d78e9 |
@@ -1,14 +0,0 @@
|
||||
xCAT - eXtreme Cloud Administration Toolkit
|
||||
|
||||
xCAT is a toolkit for the deployment and administration of clusters.
|
||||
|
||||
xCAT documentation is available at: http://xcat.sourceforge.net/
|
||||
|
||||
xCAT is made available as open source software under the EPL license:
|
||||
http://www.opensource.org/licenses/eclipse-1.0.php
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Executable
+241
@@ -0,0 +1,241 @@
|
||||
#!/bin/sh
|
||||
# Update GSA Ubuntu Repositories or create a local repository
|
||||
#
|
||||
# Author: Leonardo Tonetto (tonetto@linux.vnet.ibm.com)
|
||||
# Revisor: Arif Ali (aali@ocf.co.uk)
|
||||
#
|
||||
# After running this script, add the following line to
|
||||
# /etc/apt/sources.list for local repository
|
||||
# deb file://<core_repo_path>/xcat-core/ maverick main
|
||||
# deb file://<dep_repo_path>/xcat-dep/ maverick main
|
||||
#
|
||||
|
||||
# For the purpose of getting the distribution name
|
||||
|
||||
# Supported distributions
|
||||
dists="squeeze"
|
||||
|
||||
a_flag= # automatic flag - only update if repo was updated
|
||||
c_flag= # xcat-core (trunk-delvel) path
|
||||
d_flag= # xcat-dep (trunk) path
|
||||
local_flag= # build the repository localy
|
||||
|
||||
while getopts 'c:d:u:p:l:a' OPTION
|
||||
do
|
||||
case $OPTION in
|
||||
c) c_flag=1
|
||||
xcat_core_path="$OPTARG"
|
||||
;;
|
||||
d) d_flag=1
|
||||
xcat_dep_path="$OPTARG"
|
||||
;;
|
||||
l) local_flag=1
|
||||
local_repo_path="$OPTARG"
|
||||
;;
|
||||
a) a_flag=1
|
||||
;;
|
||||
|
||||
?) printf "Usage: %s -c <core_trunk_path> [-d <dep_trunk_path>] -l <local-repo_path> [-a]\n" $(basename $0) >&2
|
||||
echo "-a Automatic: update only if there's any update on repo"
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
done
|
||||
shift $(($OPTIND - 1))
|
||||
|
||||
if [ -z "$c_flag" -a -z "$d_flag" ]
|
||||
then
|
||||
printf "Usage: %s -c <core_trunk_path> [-d <dep_trunk_path>] { -l <local-repo_path> | [-u <gsa_id> -p <gsa_passwd>] } [-a]\n" $(basename $0) >&2
|
||||
echo "-a Automatic: update only if there's any update on repo"
|
||||
exit 2
|
||||
fi
|
||||
if [ ! -d $xcat_core_path ]
|
||||
then
|
||||
printf "%s: No such directory\n" "$xcat_core_path" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
if [ "$d_flag" ]
|
||||
then
|
||||
if [ ! -d $xcat_dep_path ]
|
||||
then
|
||||
printf "%s: No such directory\n" "$xcat_dep_path" >&2
|
||||
exit 2
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$local_flag" ]
|
||||
then
|
||||
repo_xcat_core_path=$local_repo_path"/xcat-core"
|
||||
repo_xcat_dep_path=$local_repo_path"/xcat-dep"
|
||||
else
|
||||
printf "Usage: %s -c <core_trunk_path> [-d <dep_trunk_path>] -l <local-repo_path> [-a]\n" $(basename $0) >&2
|
||||
echo "-a Automatic: update only if there's any update on repo"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
if [ "$a_flag" ]
|
||||
then
|
||||
touch svcupdate.trace
|
||||
SVCUP='svcupdate.trace'
|
||||
svn update $xcat_core_path 1> $SVCUP 2>&1
|
||||
if ! grep 'Tree is up to date' $SVCUP
|
||||
then
|
||||
update_core=1
|
||||
else
|
||||
update_core=
|
||||
fi
|
||||
rm -f $SVCUP
|
||||
else
|
||||
update_core=1
|
||||
fi
|
||||
if [ "$c_flag" -a "$update_core" ]
|
||||
then
|
||||
echo "###############################"
|
||||
echo "# Building xcat-core packages #"
|
||||
echo "###############################"
|
||||
|
||||
CMD_PATH=`pwd`
|
||||
cd $xcat_core_path
|
||||
./build-debs-all "snap" "Nightly_Builds"
|
||||
|
||||
echo "#################################"
|
||||
echo "# Creating xcat-core repository #"
|
||||
echo "#################################"
|
||||
|
||||
if [ -d $repo_xcat_core_path ]; then
|
||||
rm -rf $repo_xcat_core_path
|
||||
fi
|
||||
mkdir -p $repo_xcat_core_path/conf
|
||||
|
||||
find . -iname '*.deb' -exec mv {} $repo_xcat_core_path \;
|
||||
|
||||
rm -rf debs/
|
||||
cd $CMD_PATH
|
||||
|
||||
rm -rf $repo_xcat_core_path/conf/distributions
|
||||
|
||||
for dist in $dists; do
|
||||
cat << __EOF__ >> $repo_xcat_core_path/conf/distributions
|
||||
Origin: xCAT internal repository
|
||||
Label: xcat-core bazaar repository
|
||||
Codename: $dist
|
||||
Architectures: amd64
|
||||
Components: main
|
||||
Description: Repository automatically genereted conf
|
||||
|
||||
__EOF__
|
||||
done
|
||||
|
||||
cat << __EOF__ > $repo_xcat_core_path/conf/options
|
||||
verbose
|
||||
basedir .
|
||||
__EOF__
|
||||
|
||||
for dist in $dists; do
|
||||
for file in `ls $repo_xcat_core_path/*.deb`; do
|
||||
reprepro -b $repo_xcat_core_path includedeb $dist $file;
|
||||
done
|
||||
done
|
||||
|
||||
mv $xcat_core_path/latest_version $repo_xcat_core_path/xcat-core_latest-build
|
||||
|
||||
cat << '__EOF__' > $repo_xcat_core_path/mklocalrepo.sh
|
||||
codename=`lsb_release -a 2>null | grep Codename | awk '{print $2}'`
|
||||
cd `dirname $0`
|
||||
echo deb file://"`pwd`" $codename main > /etc/apt/sources.list.d/xcat-core.list
|
||||
__EOF__
|
||||
|
||||
chmod 775 $repo_xcat_core_path/mklocalrepo.sh
|
||||
rm -rf $repo_xcat_core_path/*.deb
|
||||
|
||||
if [ -z "$local_flag" ]
|
||||
then
|
||||
echo "###############################"
|
||||
echo "# Updating GSA xcat-core repo #"
|
||||
echo "###############################"
|
||||
lftp -e "mirror -R --delete-first $repo_xcat_core_path /projects/i/ipl-xcat/ubuntu/; exit;" -u $gsa_id,$gsa_passwd -p 22 sftp://ausgsa.ibm.com
|
||||
fi ### if [ -z "$local_flag" ]
|
||||
fi ### if [ "$a_flag" ]
|
||||
|
||||
if [ "$a_flag" -a "$d_flag" ]
|
||||
then
|
||||
touch svcupdate.trace
|
||||
SVCUP='svcupdate.trace'
|
||||
svn update $xcat_dep_path 1> $SVCUP 2>&1
|
||||
if ! grep 'Tree is up to date' $SVCUP
|
||||
then
|
||||
update_dep=1
|
||||
else
|
||||
update_dep=
|
||||
fi
|
||||
rm -f $SVCUP
|
||||
else
|
||||
update_dep=1
|
||||
fi
|
||||
if [ "$d_flag" -a "$update_dep" ]
|
||||
then
|
||||
echo "##############################"
|
||||
echo "# Building xcat-dep packages #"
|
||||
echo "##############################"
|
||||
|
||||
CMD_PATH=`pwd`
|
||||
cd $xcat_dep_path
|
||||
./build-debs-all "snap" "Nightly_Builds"
|
||||
|
||||
echo "################################"
|
||||
echo "# Creating xcat-dep repository #"
|
||||
echo "################################"
|
||||
rm -rf $repo_xcat_dep_path
|
||||
mkdir -p $repo_xcat_dep_path/conf
|
||||
find $xcat_dep_path -iname '*.deb' -exec cp {} $repo_xcat_dep_path \;
|
||||
|
||||
rm -rf $repo_xcat_core_path/conf/distributions
|
||||
|
||||
for dist in $dists; do
|
||||
cat << __EOF__ >> $repo_xcat_dep_path/conf/distributions
|
||||
Origin: xCAT internal repository
|
||||
Label: xcat-dep bazaar repository
|
||||
Codename: $dist
|
||||
Architectures: amd64
|
||||
Components: main
|
||||
Description: Repository automatically genereted conf
|
||||
|
||||
__EOF__
|
||||
done
|
||||
|
||||
cat << __EOF__ > $repo_xcat_dep_path/conf/options
|
||||
verbose
|
||||
basedir .
|
||||
__EOF__
|
||||
|
||||
for dist in $dists; do
|
||||
for file in `ls $repo_xcat_dep_path/*.deb`; do
|
||||
reprepro -b $repo_xcat_dep_path includedeb $dist $file;
|
||||
done
|
||||
done
|
||||
|
||||
cat << '__EOF__' > $repo_xcat_dep_path/mklocalrepo.sh
|
||||
codename=`lsb_release -a 2>null | grep Codename | awk '{print $2}'`
|
||||
cd `dirname $0`
|
||||
echo deb file://"`pwd`" $codename main > /etc/apt/sources.list.d/xcat-dep.list
|
||||
__EOF__
|
||||
|
||||
chmod 775 $repo_xcat_dep_path/mklocalrepo.sh
|
||||
rm -rf $repo_xcat_dep_path/*.deb
|
||||
|
||||
if [ -z "$local_flag" ]
|
||||
then
|
||||
echo "##############################"
|
||||
echo "# Updating GSA xcat-dep repo #"
|
||||
echo "##############################"
|
||||
lftp -e "mirror -R --delete-first $repo_xcat_dep_path /projects/i/ipl-xcat/ubuntu/; exit;" -u $gsa_id,$gsa_passwd -p 22 sftp://ausgsa.ibm.com
|
||||
fi ### if [ -z "$local_flag" ]
|
||||
fi ### if [ "$d_flag" -a "$a_flag"]
|
||||
|
||||
if [ -z "$local_flag" ] # delete the temp repo after upload is done
|
||||
then
|
||||
rm -rf ./gsa-repo_temp
|
||||
fi
|
||||
|
||||
exit 0
|
||||
+27
-79
@@ -53,7 +53,7 @@ for i in $*; do
|
||||
done
|
||||
|
||||
# Supported distributions
|
||||
dists="maverick natty oneiric precise saucy trusty"
|
||||
dists="maverick natty oneiric precise"
|
||||
|
||||
c_flag= # xcat-core (trunk-delvel) path
|
||||
d_flag= # xcat-dep (trunk) path
|
||||
@@ -86,7 +86,7 @@ if [ "$c_flag" -a "$d_flag" ];then
|
||||
exit 2
|
||||
fi
|
||||
|
||||
uploader="ligc"
|
||||
uploader="bp-sawyers"
|
||||
# Find where this script is located to set some build variables
|
||||
old_pwd=`pwd`
|
||||
cd `dirname $0`
|
||||
@@ -194,39 +194,27 @@ then
|
||||
if [ ! -d ../../$package_dir_name ];then
|
||||
mkdir -p "../../$package_dir_name"
|
||||
fi
|
||||
packages="xCAT-client xCAT-genesis-scripts perl-xCAT xCAT-server xCAT-UI xCAT xCATsn xCAT-test xCAT-OpenStack xCAT-OpenStack-baremetal"
|
||||
target_archs=(amd64 ppc64el)
|
||||
packages="xCAT-client xCAT-genesis-scripts perl-xCAT xCAT-server xCAT-UI xCAT xCATsn xCAT-test xCAT-OpenStack"
|
||||
|
||||
for file in `echo $packages`
|
||||
do
|
||||
file_low=`echo $file | tr '[A-Z]' '[a-z]'`
|
||||
if [ "$file" = "xCAT" ]; then
|
||||
target_archs="amd64 ppc64el"
|
||||
else
|
||||
target_archs="all"
|
||||
fi
|
||||
for target_arch in `echo $target_archs`
|
||||
do
|
||||
if grep -q $file $update_log || [ "$BUILDALL" == 1 -o "$file" = "perl-xCAT" ]; then
|
||||
rm -f ../../$package_dir_name/${file_low}_*.$target_arch.deb
|
||||
#only for genesis package
|
||||
rm -f ../../$package_dir_name/${file_low}-amd64_*.deb
|
||||
cd $file
|
||||
dch -v $pkg_version -b -c debian/changelog $build_string
|
||||
if [ "$target_arch" = "all" ]; then
|
||||
dpkg-buildpackage -uc -us
|
||||
else
|
||||
dpkg-buildpackage -uc -us -a$target_arch
|
||||
fi
|
||||
rc=$?
|
||||
if [ $rc -gt 0 ]; then
|
||||
echo "Error: $file build package failed exit code $rc"
|
||||
fi
|
||||
cd -
|
||||
find $file -maxdepth 3 -type d -name "${file_low}*" | grep debian | xargs rm -rf
|
||||
find $file -maxdepth 3 -type f -name "files" | grep debian | xargs rm -rf
|
||||
mv ${file_low}* ../../$package_dir_name/
|
||||
if grep -q $file $update_log || [ "$BUILDALL" == 1 -o "$file" = "perl-xCAT" ]; then
|
||||
rm -f ../../$package_dir_name/${file_low}_*.deb
|
||||
#only for genesis package
|
||||
rm -f ../../$package_dir_name/${file_low}-amd64_*.deb
|
||||
cd $file
|
||||
dch -v $pkg_version -b -c debian/changelog $build_string
|
||||
dpkg-buildpackage -uc -us
|
||||
rc=$?
|
||||
if [ $rc -gt 0 ]; then
|
||||
echo "Error: $file build package failed exit code $rc"
|
||||
fi
|
||||
done
|
||||
cd -
|
||||
find $file -maxdepth 3 -type d -name "${file_low}*" | grep debian | xargs rm -rf
|
||||
find $file -maxdepth 3 -type f -name "files" | grep debian | xargs rm -rf
|
||||
mv ${file_low}* ../../$package_dir_name/
|
||||
fi
|
||||
done
|
||||
|
||||
find ../../$package_dir_name/* ! -name *.deb | xargs rm -f
|
||||
@@ -262,16 +250,11 @@ then
|
||||
mkdir conf
|
||||
|
||||
for dist in $dists; do
|
||||
if [ "$dist" = "trusty" ]; then
|
||||
tmp_out_arch="amd64 ppc64el"
|
||||
else
|
||||
tmp_out_arch="amd64"
|
||||
fi
|
||||
cat << __EOF__ >> conf/distributions
|
||||
Origin: xCAT internal repository
|
||||
Label: xcat-core bazaar repository
|
||||
Codename: $dist
|
||||
Architectures: $tmp_out_arch
|
||||
Architectures: amd64
|
||||
Components: main
|
||||
Description: Repository automatically genereted conf
|
||||
SignWith: yes
|
||||
@@ -286,29 +269,17 @@ basedir .
|
||||
__EOF__
|
||||
|
||||
#import the deb packages into the repo
|
||||
amd_files=`ls ../$package_dir_name/*.deb | grep -v "ppc64el"`
|
||||
all_files=`ls ../$package_dir_name/*.deb`
|
||||
for dist in $dists; do
|
||||
if [ "$dist" = "trusty" ]; then
|
||||
deb_files=$all_files
|
||||
else
|
||||
deb_files=$amd_files
|
||||
fi
|
||||
for file in $deb_files; do
|
||||
for file in `ls ../$package_dir_name/*.deb`; do
|
||||
reprepro -b ./ includedeb $dist $file;
|
||||
done
|
||||
done
|
||||
|
||||
#create the mklocalrepo script
|
||||
cat << '__EOF__' > mklocalrepo.sh
|
||||
cat << __EOF__ > mklocalrepo.sh
|
||||
. /etc/lsb-release
|
||||
cd `dirname $0`
|
||||
host_arch=`uname -m`
|
||||
if [ "$host_arch" != "ppc64le" ];then
|
||||
host_arch="amd64"
|
||||
else
|
||||
host_arch="ppc64el"
|
||||
fi
|
||||
echo deb [arch=$host_arch] file://"`pwd`" $DISTRIB_CODENAME main > /etc/apt/sources.list.d/xcat-core.list
|
||||
echo deb file://"`pwd`" $DISTRIB_CODENAME main > /etc/apt/sources.list.d/xcat-core.list
|
||||
__EOF__
|
||||
|
||||
chmod 775 mklocalrepo.sh
|
||||
@@ -382,16 +353,11 @@ then
|
||||
|
||||
#create the conf/distributions file
|
||||
for dist in $dists; do
|
||||
if [ "$dist" = "trusty" ]; then
|
||||
tmp_out_arch="amd64 ppc64el"
|
||||
else
|
||||
tmp_out_arch="amd64"
|
||||
fi
|
||||
cat << __EOF__ >> conf/distributions
|
||||
Origin: xCAT internal repository
|
||||
Label: xcat-dep bazaar repository
|
||||
Codename: $dist
|
||||
Architectures: $tmp_out_arch
|
||||
Architectures: amd64
|
||||
Components: main
|
||||
Description: Repository automatically genereted conf
|
||||
SignWith: yes
|
||||
@@ -405,16 +371,8 @@ ask-passphrase
|
||||
basedir .
|
||||
__EOF__
|
||||
|
||||
#import the deb packages into the repo
|
||||
amd_files=`ls ../debs/*.deb | grep -v "ppc64el"`
|
||||
all_files=`ls ../debs/*.deb`
|
||||
for dist in $dists; do
|
||||
if [ "$dist" = "trusty" ]; then
|
||||
deb_files=$all_files
|
||||
else
|
||||
deb_files=$amd_files
|
||||
fi
|
||||
for file in $deb_files; do
|
||||
for file in `ls ../debs/*.deb`; do
|
||||
reprepro -b ./ includedeb $dist $file;
|
||||
done
|
||||
done
|
||||
@@ -422,13 +380,7 @@ __EOF__
|
||||
cat << '__EOF__' > mklocalrepo.sh
|
||||
. /etc/lsb-release
|
||||
cd `dirname $0`
|
||||
host_arch=`uname -m`
|
||||
if [ "$host_arch" != "ppc64le" ];then
|
||||
host_arch="amd64"
|
||||
else
|
||||
host_arch="ppc64el"
|
||||
fi
|
||||
echo deb [arch=$host_arch] file://"`pwd`" $DISTRIB_CODENAME main > /etc/apt/sources.list.d/xcat-dep.list
|
||||
echo deb file://"`pwd`" $DISTRIB_CODENAME main > /etc/apt/sources.list.d/xcat-dep.list
|
||||
__EOF__
|
||||
|
||||
chmod 775 mklocalrepo.sh
|
||||
@@ -461,10 +413,6 @@ __EOF__
|
||||
while [ $((i+=1)) -le 5 ] && ! rsync -urLv --delete xcat-dep ${uploader},xcat@web.sourceforge.net:${sf_dir}/ubuntu/
|
||||
do : ; done
|
||||
#upload the tarball
|
||||
i=0
|
||||
echo "Uploading $dep_tar_name to ${sf_dir}/xcat-dep/2.x_Ubuntu/ ..."
|
||||
while [ $((i+=1)) -le 5 ] && ! rsync -v $dep_tar_name ${uploader},xcat@web.sourceforge.net:${sf_dir}/xcat-dep/2.x_Ubuntu/
|
||||
do : ; done
|
||||
cd $old_pwd
|
||||
fi
|
||||
exit 0
|
||||
|
||||
+7
-11
@@ -41,13 +41,11 @@ UPLOADUSER=bp-sawyers
|
||||
FRS=/home/frs/project/x/xc/xcat
|
||||
|
||||
# These are the rpms that should be built for each kind of xcat build
|
||||
ALLBUILD="perl-xCAT xCAT-client xCAT-server xCAT-IBMhpc xCAT-rmc xCAT-UI xCAT-test xCAT-buildkit xCAT xCATsn xCAT-genesis-scripts xCAT-OpenStack xCAT-SoftLayer xCAT-OpenStack-baremetal"
|
||||
ALLBUILD="perl-xCAT xCAT-client xCAT-server xCAT-IBMhpc xCAT-rmc xCAT-UI xCAT-test xCAT-buildkit xCAT xCATsn xCAT-genesis-scripts xCAT-OpenStack"
|
||||
ZVMBUILD="perl-xCAT xCAT-server xCAT-UI"
|
||||
ZVMLINK="xCAT-client xCAT xCATsn"
|
||||
# xCAT has PCM specific configuration - conserver-xcat, syslinux-xcat
|
||||
# xCAT-server has PCM specific configuration - RESTAPI(perl-JSON)
|
||||
PCMBUILD="xCAT xCAT-server"
|
||||
PCMLINK="perl-xCAT xCAT-client xCAT-buildkit xCAT-genesis-scripts-x86_64"
|
||||
PCMBUILD="xCAT"
|
||||
PCMLINK="perl-xCAT xCAT-client xCAT-server xCAT-buildkit xCAT-genesis-scripts-x86_64"
|
||||
# Note: for FSM, the FlexCAT rpm is built separately from gsa/git
|
||||
FSMBUILD="perl-xCAT xCAT-client xCAT-server"
|
||||
FSMLINK=""
|
||||
@@ -239,11 +237,10 @@ if [ "$OSNAME" = "AIX" ]; then
|
||||
fi
|
||||
|
||||
# Build the rest of the noarch rpms
|
||||
for rpmname in xCAT-client xCAT-server xCAT-IBMhpc xCAT-rmc xCAT-UI xCAT-test xCAT-buildkit xCAT-SoftLayer; do
|
||||
for rpmname in xCAT-client xCAT-server xCAT-IBMhpc xCAT-rmc xCAT-UI xCAT-test xCAT-buildkit; do
|
||||
#if [ "$EMBED" = "zvm" -a "$rpmname" != "xCAT-server" -a "$rpmname" != "xCAT-UI" ]; then continue; fi # for zvm embedded env only need to build server and UI
|
||||
if [[ " $EMBEDBUILD " != *\ $rpmname\ * ]]; then continue; fi
|
||||
if [ "$OSNAME" = "AIX" -a "$rpmname" = "xCAT-buildkit" ]; then continue; fi # do not build xCAT-buildkit on aix
|
||||
if [ "$OSNAME" = "AIX" -a "$rpmname" = "xCAT-SoftLayer" ]; then continue; fi # do not build xCAT-softlayer on aix
|
||||
if $GREP $rpmname $GITUP || [ "$BUILDALL" == 1 ]; then
|
||||
UPLOAD=1
|
||||
maker $rpmname
|
||||
@@ -275,19 +272,19 @@ if [ "$OSNAME" != "AIX" ]; then
|
||||
fi
|
||||
|
||||
# Build the xCAT and xCATsn rpms for all platforms
|
||||
for rpmname in xCAT xCATsn xCAT-OpenStack xCAT-OpenStack-baremetal; do
|
||||
for rpmname in xCAT xCATsn xCAT-OpenStack; do
|
||||
#if [ "$EMBED" = "zvm" ]; then break; fi
|
||||
if [[ " $EMBEDBUILD " != *\ $rpmname\ * ]]; then continue; fi
|
||||
if [ $SOMETHINGCHANGED == 1 -o "$BUILDALL" == 1 ]; then # used to be: if $GREP -E "^[UAD] +$rpmname/" $GITUP; then
|
||||
UPLOAD=1
|
||||
ORIGFAILEDRPMS="$FAILEDRPMS"
|
||||
if [ "$OSNAME" = "AIX" ]; then
|
||||
if [ "$rpmname" = "xCAT-OpenStack" ] || [ "$rpmname" = "xCAT-OpenStack-baremetal" ]; then continue; fi # do not bld openstack on aix
|
||||
if [ "$rpmname" = "xCAT-OpenStack" ]; then continue; fi # do not bld openstack on aix
|
||||
./makerpm $rpmname "$EMBED"
|
||||
if [ $? -ne 0 ]; then FAILEDRPMS="$FAILEDRPMS $rpmname"; fi
|
||||
else
|
||||
for arch in x86_64 ppc64 s390x; do
|
||||
if [ "$rpmname" = "xCAT-OpenStack" -a "$arch" != "x86_64" ] || [ "$rpmname" = "xCAT-OpenStack-baremetal" -a "$arch" != "x86_64" ] ; then continue; fi # only bld openstack for x86_64 for now
|
||||
if [ "$rpmname" = "xCAT-OpenStack" -a "$arch" != "x86_64" ]; then continue; fi # only bld openstack for x86_64 for now
|
||||
./makerpm $rpmname $arch "$EMBED"
|
||||
if [ $? -ne 0 ]; then FAILEDRPMS="$FAILEDRPMS $rpmname-$arch"; fi
|
||||
done
|
||||
@@ -499,7 +496,6 @@ if [ "$OSNAME" != "AIX" -a "$REL" = "devel" -a "$PROMOTE" != 1 -a -z "$EMBED" ];
|
||||
rpm2cpio ../$XCATCORE/xCAT-test-*.$NOARCH.rpm | cpio -id '*.html'
|
||||
rpm2cpio ../$XCATCORE/xCAT-buildkit-*.$NOARCH.rpm | cpio -id '*.html'
|
||||
rpm2cpio ../$XCATCORE/xCAT-OpenStack-*.x86_64.rpm | cpio -id '*.html'
|
||||
rpm2cpio ../$XCATCORE/xCAT-SoftLayer-*.$NOARCH.rpm | cpio -id '*.html'
|
||||
i=0
|
||||
while [ $((i+=1)) -le 5 ] && ! rsync $verboseflag -r opt/xcat/share/doc/man1 opt/xcat/share/doc/man3 opt/xcat/share/doc/man5 opt/xcat/share/doc/man7 opt/xcat/share/doc/man8 $UPLOADUSER,xcat@web.sourceforge.net:htdocs/
|
||||
do : ; done
|
||||
|
||||
+18
-28
@@ -138,21 +138,8 @@ if [ "$PERLVER" == "v5.8.2" ]; then
|
||||
OSVER='5.3'
|
||||
elif [ "$PERLVER" == "v5.8.8" ]; then
|
||||
OSVER='6.1'
|
||||
aixver=`lslpp -lc|grep 'bos.rte:'|head -1|cut -d: -f3`
|
||||
if [[ $aixver < '6.1.9.0' ]]; then
|
||||
AIX61Y=0
|
||||
else
|
||||
AIX61Y=1
|
||||
fi
|
||||
elif [ "$PERLVER" == "v5.10.1" ]; then
|
||||
OSVER='7.1'
|
||||
aixver=`lslpp -lc|grep 'bos.rte:'|head -1|cut -d: -f3`
|
||||
if [[ $aixver < '7.1.3.0' ]]; then
|
||||
AIX71L=0
|
||||
else
|
||||
AIX71L=1
|
||||
fi
|
||||
|
||||
else
|
||||
echo "Error: the perl version of '$PERLVER' is not one that instoss understands. Exiting..."
|
||||
exit 2
|
||||
@@ -169,30 +156,33 @@ echo "Running updtvpkg. This could take a few minutes."
|
||||
/usr/sbin/updtvpkg
|
||||
echo "updtvpkg has completed."
|
||||
|
||||
# unixODBC is required by pyodbc, so install it first
|
||||
rpm -Uvh unixODBC*
|
||||
# Now install the bulk of the rpms, one at a time, in case some are already installed
|
||||
for i in `ls *.rpm|grep -v -E '^tcl-|^tk-|^expect-|^unixODBC-|^xCAT-UI-deps|^perl-DBD-DB2Lite|^net-snmp'`; do
|
||||
for i in `ls *.rpm|grep -v -E '^tcl-|^tk-|^expect-|^unixODBC-|^xCAT-UI-deps|^perl-DBD-DB2Lite'`; do
|
||||
if [ "$i" == "perl-Net-DNS-0.66-1.aix5.3.ppc.rpm" ]; then
|
||||
opts="--nodeps"
|
||||
else
|
||||
opts=""
|
||||
fi
|
||||
|
||||
# On 7.1L and 6.1Y we need a newer version of perl-Net_SSLeay.pm
|
||||
if [[ $AIX71L -eq 1 || $AIX61Y -eq 1 ]]; then
|
||||
if [[ $i == perl-Net_SSLeay.pm-1.30-* ]]; then continue; fi # skip the old rpm
|
||||
else
|
||||
if [[ $i == perl-Net_SSLeay.pm-1.55-* ]]; then continue; fi # skip the new rpm
|
||||
fi
|
||||
|
||||
# just in case we need it sometime, this next if stmt would mean: if it does not start with perl-DBD-DB2
|
||||
#if [ "${i#perl-DBD-DB2}" == "$i" ]; then
|
||||
|
||||
echo rpm -Uvh $opts $i
|
||||
rpm -Uvh $opts $i
|
||||
done
|
||||
# Have to upgrade all of the net-snmp rpms together because they depend on each other.
|
||||
# Also, they require bash, so do it after the loop, rather than before
|
||||
rpm -Uvh net-snmp*
|
||||
|
||||
# don't try to install tcl, tk, or expect if they are already installed!
|
||||
# this section about expect/tcl/tk can be removed once 2.8 releases, because 2.8 no longer requires expect
|
||||
lslpp -l | grep expect.base > /dev/null 2>&1
|
||||
if [ $? -gt 0 ]; then
|
||||
if [ "$OSVER" == "5.3" ]; then
|
||||
for i in tcl-*.rpm tk-*.rpm expect-*.rpm; do
|
||||
echo rpm -Uvh $i
|
||||
rpm -Uvh $i
|
||||
done
|
||||
else
|
||||
echo "The expect.base, tcl.base, and tk.base filesets must also be installed before installing the xCAT RPMs from xcat-core."
|
||||
fi
|
||||
fi
|
||||
EOF
|
||||
# end of instoss file content ---------------------------------------------
|
||||
|
||||
@@ -206,7 +196,7 @@ if [ "$OSNAME" == "AIX" ]; then
|
||||
else
|
||||
SYSGRP=root
|
||||
fi
|
||||
chgrp -R -h $SYSGRP *
|
||||
chgrp -R $SYSGRP *
|
||||
chmod -R g+w *
|
||||
|
||||
# Build the tarball
|
||||
|
||||
-161
@@ -1,161 +0,0 @@
|
||||
#######################################################################
|
||||
#build script for local usage
|
||||
#used for Linux/AIX/Ubuntu
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
|
||||
OSNAME=$(uname)
|
||||
NAMEALL=$(uname -a)
|
||||
|
||||
for i in $*; do
|
||||
# upper case the variable name
|
||||
varstring=`echo "$i"|cut -d '=' -f 1|tr '[a-z]' '[A-Z]'`=`echo "$i"|cut -d '=' -f 2`
|
||||
export $varstring
|
||||
done
|
||||
|
||||
if [ -z "$CURDIR" ]; then
|
||||
echo "get current directory!"
|
||||
CURDIR=$(pwd)
|
||||
fi
|
||||
|
||||
echo "CURDIR is $CURDIR"
|
||||
echo "OSNAME is $OSNAME!"
|
||||
echo "NAMEALL is $NAMEALL"
|
||||
|
||||
grep -i 'SUSE' /etc/issue
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "This is a SUSE system!"
|
||||
OS="SUSE";
|
||||
fi
|
||||
|
||||
|
||||
ls $CURDIR/makerpm
|
||||
|
||||
if [ $? -gt 0 ]; then
|
||||
echo "Error:no repo exist, exit 1."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Get a lock, so can not do 2 builds at once
|
||||
exec 8>/var/lock/xcatbld.lock
|
||||
if ! flock -n 8; then
|
||||
echo "Can't get lock /var/lock/xcatbld.lock. Someone else must be doing a build right now. Exiting...."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
#delete old package if there is
|
||||
rm -rf $CURDIR/build/
|
||||
cd $CURDIR
|
||||
|
||||
echo "==============================================="
|
||||
echo $NAMEALL | egrep "Ubuntu"
|
||||
|
||||
#Check if it is an Ubuntu system
|
||||
if [ $? -eq 0 ]; then
|
||||
|
||||
echo "This is an Ubuntu system"
|
||||
pkg_type="snap"
|
||||
build_string="Snap_Build"
|
||||
cur_date=`date +%Y%m%d`
|
||||
short_ver=`cat Version|cut -d. -f 1,2`
|
||||
pkg_version="${short_ver}-${pkg_type}${cur_date}"
|
||||
|
||||
mkdir -p $CURDIR/build
|
||||
|
||||
for rpmname in xCAT-client xCAT-genesis-scripts perl-xCAT xCAT-server xCAT xCATsn xCAT-test; do
|
||||
rpmname_low=`echo $rpmname | tr '[A-Z]' '[a-z]'`
|
||||
echo "============================================"
|
||||
echo "$rpmname_low"
|
||||
cd $rpmname
|
||||
dch -v $pkg_version -b -c debian/changelog $build_string
|
||||
dpkg-buildpackage -uc -us
|
||||
rc=$?
|
||||
if [ $rc -gt 0 ]; then
|
||||
echo "Error: $rpmname build package failed exit code $rc"
|
||||
fi
|
||||
cd -
|
||||
mv ${rpmname_low}* $CURDIR/build
|
||||
|
||||
done
|
||||
#delete all files except .deb file
|
||||
find $CURDIR/build/* ! -name *.deb | xargs rm -f
|
||||
|
||||
else
|
||||
#This is not an Ubuntu system
|
||||
echo "This is an $OSNAME system"
|
||||
|
||||
if [ "$OS" = "SUSE" ]; then
|
||||
rm -rf /usr/src/packages/RPMS/noarch/*
|
||||
rm -rf /usr/src/packages/RPMS/x86_64/*
|
||||
rm -rf /usr/src/packages/RPMS/ppc64/*
|
||||
else
|
||||
rm -rf /root/rpmbuild/RPMS/noarch/*
|
||||
rm -rf /root/rpmbuild/RPMS/x86_64/*
|
||||
rm -rf /root/rpmbuild/RPMS/ppc64/*
|
||||
fi
|
||||
|
||||
mkdir -p $CURDIR/build/
|
||||
|
||||
#always build perl-xCAT
|
||||
$CURDIR/makerpm perl-xCAT
|
||||
|
||||
|
||||
# Build the rest of the noarch rpms
|
||||
for rpmname in xCAT-client xCAT-server xCAT-IBMhpc xCAT-rmc xCAT-test xCAT-buildkit; do
|
||||
if [ "$OSNAME" = "AIX" -a "$rpmname" = "xCAT-buildkit" ]; then continue; fi
|
||||
$CURDIR/makerpm $rpmname
|
||||
done
|
||||
|
||||
#build xCAT-genesis-scripts if it is x86_64 platform
|
||||
ARCH=$(uname -p)
|
||||
if [ "$ARCH" = "x64_64" ]; then
|
||||
$CURDIR/makerpm xCAT-genesis-scripts x86_64
|
||||
fi
|
||||
|
||||
|
||||
# Build the xCAT and xCATsn rpms for all platforms
|
||||
for rpmname in xCAT xCATsn; do
|
||||
if [ "$OSNAME" = "AIX" ]; then
|
||||
$CURDIR/makerpm $rpmname
|
||||
if [ $? -ne 0 ]; then FAILEDRPMS="$FAILEDRPMS $rpmname"; fi
|
||||
else
|
||||
for arch in x86_64 ppc64 s390x; do
|
||||
$CURDIR/makerpm $rpmname $arch
|
||||
if [ $? -ne 0 ]; then FAILEDRPMS="$FAILEDRPMS $rpmname-$arch"; fi
|
||||
done
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$OS" = "SUSE" ]; then
|
||||
cp /usr/src/packages/RPMS/noarch/* $CURDIR/build/
|
||||
cp /usr/src/packages/RPMS/x86_64/* $CURDIR/build/
|
||||
cp /usr/src/packages/RPMS/ppc64/* $CURDIR/build/
|
||||
else
|
||||
cp /root/rpmbuild/RPMS/noarch/* $CURDIR/build/
|
||||
cp /root/rpmbuild/RPMS/x86_64/* $CURDIR/build/
|
||||
cp /root/rpmbuild/RPMS/ppc64/* $CURDIR/build/
|
||||
fi
|
||||
|
||||
#begin to create repo for redhat platform
|
||||
|
||||
grep -i 'Red' /etc/issue;
|
||||
if [ "$OSNAME" != "AIX" -a $? -eq 0 ]; then
|
||||
cat >$CURDIR/build/xCAT-core.repo << EOF
|
||||
[xcat-2-core]
|
||||
name=xCAT 2 Core packages
|
||||
baseurl=file://$CURDIR/build
|
||||
enabled=1
|
||||
gpgcheck=0
|
||||
EOF
|
||||
|
||||
cp $CURDIR/build/xCAT-core.repo /etc/yum.repos.d/
|
||||
createrepo $CURDIR/build
|
||||
else
|
||||
rm -f /etc/zypp/repos.d/xCAT-core.repo
|
||||
zypper ar file://$CURDIR/build xCAT-core
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
|
||||
@@ -10,6 +10,9 @@
|
||||
<packagereq type="required">xCAT-server</packagereq>
|
||||
<packagereq type="required">xCAT-client</packagereq>
|
||||
<packagereq type="required">perl-xCAT</packagereq>
|
||||
<packagereq type="required">xCAT-nbroot-core-x86_64</packagereq>
|
||||
<packagereq type="required">xCAT-nbroot-core-x86</packagereq>
|
||||
<packagereq type="optional">xCAT-nbroot-core-ppc64</packagereq>
|
||||
</packagelist>
|
||||
</group>
|
||||
</comps>
|
||||
|
||||
@@ -53,7 +53,6 @@ function makexcat {
|
||||
tar -X /tmp/xcat-excludes -cf $RPMROOT/SOURCES/templates.tar templates
|
||||
gzip -f $RPMROOT/SOURCES/templates.tar
|
||||
cp xcat.conf $RPMROOT/SOURCES
|
||||
cp xcat.conf.apach24 $RPMROOT/SOURCES
|
||||
cp xCATMN $RPMROOT/SOURCES
|
||||
else # xCATsn
|
||||
tar -X /tmp/xcat-excludes -cf $RPMROOT/SOURCES/license.tar LICENSE.html
|
||||
@@ -76,16 +75,13 @@ function makexcat {
|
||||
tar --exclude .svn --exclude upflag -czf $RPMROOT/SOURCES/postscripts.tar.gz postscripts LICENSE.html
|
||||
tar --exclude .svn -czf $RPMROOT/SOURCES/prescripts.tar.gz prescripts
|
||||
tar --exclude .svn -czf $RPMROOT/SOURCES/templates.tar.gz templates
|
||||
tar --exclude .svn -czf $RPMROOT/SOURCES/winpostscripts.tar.gz winpostscripts
|
||||
cp xcat.conf $RPMROOT/SOURCES
|
||||
cp xcat.conf.apach24 $RPMROOT/SOURCES
|
||||
cp xCATMN $RPMROOT/SOURCES
|
||||
cd - >/dev/null
|
||||
elif [ "$RPMNAME" = "xCATsn" ]; then
|
||||
cd `dirname $0`/$RPMNAME
|
||||
tar --exclude .svn -czf $RPMROOT/SOURCES/license.tar.gz LICENSE.html
|
||||
cp xcat.conf $RPMROOT/SOURCES
|
||||
cp xcat.conf.apach24 $RPMROOT/SOURCES
|
||||
cp xCATSN $RPMROOT/SOURCES
|
||||
cd - >/dev/null
|
||||
elif [ "$RPMNAME" = "xCAT-buildkit" ]; then
|
||||
@@ -106,23 +102,7 @@ function makexcat {
|
||||
fi
|
||||
}
|
||||
|
||||
# make ironic rpm for ironic baremetal driver
|
||||
function makeironic {
|
||||
RPMNAME="$1"
|
||||
ARCH="$2"
|
||||
cd `dirname $0`/$RPMNAME
|
||||
cp -rf ironic_baremetal /tmp/
|
||||
cd /tmp/ironic_baremetal
|
||||
git init
|
||||
git add *
|
||||
git commit -a -m "generate rpm"
|
||||
python setup.py bdist_rpm
|
||||
rm -rf $RPMROOT/RPMS/$ARCH/
|
||||
mkdir -p $RPMROOT/RPMS/$ARCH/
|
||||
cp -rf dist/*.rpm $RPMROOT/RPMS/$ARCH/
|
||||
rm -rf /tmp/ironic_baremetal
|
||||
}
|
||||
|
||||
|
||||
|
||||
# Make the xCAT-nbroot-core rpm
|
||||
function makenbroot {
|
||||
@@ -222,6 +202,7 @@ else # linux
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
if [ "$1" = "xCAT" -o "$1" = "xCATsn" -o "$1" = "xCAT-buildkit" -o "$1" = "xCAT-OpenStack" ]; then
|
||||
exportEmbed $3
|
||||
makexcat $1 $2
|
||||
@@ -234,8 +215,6 @@ elif [ "$1" = "xCAT-genesis-builder" ]; then
|
||||
elif [ "$1" = "xCAT-genesis-scripts" ]; then
|
||||
exportEmbed $3
|
||||
makegenesisscripts $1 $2
|
||||
elif [ "$1" = "xCAT-OpenStack-ironic" ]; then
|
||||
makeironic $1 $2
|
||||
else # must be one of the noarch rpms
|
||||
exportEmbed $2
|
||||
makenoarch $1
|
||||
|
||||
@@ -262,12 +262,6 @@ expression B<($1-1)%14+1> will evaluate to B<6>.
|
||||
|
||||
See http://www.perl.com/doc/manual/html/pod/perlre.html for information on perl regular expressions.
|
||||
|
||||
=head2 Easy Regular Expressions
|
||||
|
||||
As of xCAT 2.8.1, you can use a modified version of the regular expression support described in the previous section. You do not need to enter the node information (1st part of the expression), it will be derived from the input nodename. You only need to supply the 2nd part of the expression to determine the value to give the attribute. For examples, see
|
||||
|
||||
https://sourceforge.net/apps/mediawiki/xcat/index.php?title=Listing_and_Modifying_the_Database#Easy_Regular_expressions
|
||||
|
||||
=head1 OBJECT DEFINITIONS
|
||||
|
||||
Because it can get confusing what attributes need to go in what tables, the xCAT database can also
|
||||
|
||||
@@ -48,7 +48,7 @@ binary-arch: build install
|
||||
chmod 644 `pwd`/debian/perl-xcat/opt/xcat/share/doc/man5/*
|
||||
chmod 644 `pwd`/debian/perl-xcat/opt/xcat/share/man/man7/*
|
||||
chmod 644 `pwd`/debian/perl-xcat/opt/xcat/share/doc/man7/*
|
||||
./modifyUtils `cat ../Version` `git log -n 1 | head -n 1 | cut -f 2 -d ' '`
|
||||
./modifyUtils `cat ../Version` `svn info | grep Revision | cut -d" " -f 2`
|
||||
# dh_installmenu
|
||||
# dh_installdebconf
|
||||
# dh_installlogrotate
|
||||
|
||||
@@ -1,21 +1,20 @@
|
||||
#!/bin/sh
|
||||
# Put the version, svn revision #, and build date into the Version function in Version.pm
|
||||
|
||||
if [ -z "$2" ]
|
||||
if [ -z "$1" ]
|
||||
then
|
||||
echo "modifyUtils: Error: must specify the xCAT version as an argument" >&2
|
||||
exit
|
||||
fi
|
||||
|
||||
VER=$1
|
||||
GITREF="git commit $2, "
|
||||
|
||||
BUILDDATE=`date`
|
||||
#echo ". '(built $BUILDDATE)'"
|
||||
|
||||
if [ "$(uname)" = "AIX" ]
|
||||
then
|
||||
sed -e s/"#XCATVERSIONSUBHERE"/". '$VER'"/ -e s/"#XCATSVNBUILDSUBHERE"/". ' (${GITREF}built $BUILDDATE)'"/ xCAT/Version.pm >xCAT/Version.pm.new
|
||||
sed -e s/"#XCATVERSIONSUBHERE"/". '$VER'"/ -e s/"#XCATSVNBUILDSUBHERE"/". ' (built $BUILDDATE)'"/ xCAT/Version.pm >xCAT/Version.pm.new
|
||||
mv xCAT/Version.pm.new xCAT/Version.pm
|
||||
else
|
||||
if [ -f "/etc/debian_version" ];then
|
||||
@@ -23,5 +22,5 @@ else
|
||||
else
|
||||
FILENAME="xCAT/Version.pm"
|
||||
fi
|
||||
sed -i -e s/"#XCATVERSIONSUBHERE"/". '$VER'"/ -e s/"#XCATSVNBUILDSUBHERE"/". ' (${GITREF}built $BUILDDATE)'"/ $FILENAME
|
||||
sed -i -e s/"#XCATVERSIONSUBHERE"/". '$VER'"/ -e s/"#XCATSVNBUILDSUBHERE"/". ' (built $BUILDDATE)'"/ $FILENAME
|
||||
fi
|
||||
|
||||
@@ -23,8 +23,6 @@ Provides: perl-xCAT = %{epoch}:%{version}
|
||||
Provides perl xCAT libraries for core functionality. Required for all xCAT installations.
|
||||
Includes xCAT::Table, xCAT::NodeRange, among others.
|
||||
|
||||
%define gitinfo %(git log -n 1 | head -n 1 | cut -f 2 -d ' ')
|
||||
|
||||
%define zvm %(if [ "$zvm" = "1" ];then echo 1; else echo 0; fi)
|
||||
%define fsm %(if [ "$fsm" = "1" ];then echo 1; else echo 0; fi)
|
||||
|
||||
@@ -38,7 +36,7 @@ Includes xCAT::Table, xCAT::NodeRange, among others.
|
||||
%if %fsm
|
||||
%else
|
||||
# Modify the Version() function in xCAT/Utils.pm to automatically have the correct version
|
||||
./modifyUtils %{version} %{gitinfo}
|
||||
./modifyUtils %{version}
|
||||
|
||||
# Build the pod version of the man pages for each DB table. It puts them in the man5 and man7 subdirs.
|
||||
# Then convert the pods to man pages and html pages.
|
||||
|
||||
+2
-125
@@ -500,7 +500,6 @@ sub setCFMPkglistFile {
|
||||
Arguments:
|
||||
$imagename - the specified linuximage name
|
||||
@curospkgs - the currently selected OS packages list
|
||||
$mode - using Fuzzy Matching or Exact Matching to check packages
|
||||
Returns:
|
||||
0 - update successfully
|
||||
1 - update failed
|
||||
@@ -510,22 +509,13 @@ sub setCFMPkglistFile {
|
||||
none
|
||||
Example:
|
||||
my $ret = CAT::CFMUtils->updateCFMPkglistFile($imagename, @cur_selected_pkgs);
|
||||
my $ret = CAT::CFMUtils->updateCFMPkglistFile($imagename, @cur_selected_pkgs, 1);
|
||||
|
||||
=cut
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
sub updateCFMPkglistFile {
|
||||
my ($class, $img, $ospkgs, $mode) = @_;
|
||||
|
||||
if(defined($mode)){
|
||||
# Exact Matching
|
||||
$mode = 1;
|
||||
}else {
|
||||
# Fuzzy Matching
|
||||
$mode = 0;
|
||||
}
|
||||
|
||||
my ($class, $img, $ospkgs) = @_;
|
||||
|
||||
my @cur_selected = @$ospkgs;
|
||||
my $cfmpkglist = "/install/osimages/$img/pkglist.cfm";
|
||||
|
||||
@@ -559,14 +549,6 @@ sub updateCFMPkglistFile {
|
||||
my @selected = @$selected_ref;
|
||||
@basepkgs = xCAT::CFMUtils->arrayops("U", \@basepkgs, \@selected);
|
||||
}
|
||||
|
||||
# Fuzzy Matching
|
||||
if (not $mode){
|
||||
my ($ref1, $ref2, $ref3) = xCAT::CFMUtils->updateSelectedPkgs(\@pre_selected, \@pre_removed, \@cur_selected);
|
||||
@pre_selected = @$ref1;
|
||||
@pre_removed = @$ref2;
|
||||
@cur_selected = @$ref3;
|
||||
}
|
||||
|
||||
# get diff between previous and current selected OS packages lists
|
||||
my @diff = xCAT::CFMUtils->getPkgsDiff(\@pre_selected, \@cur_selected);
|
||||
@@ -679,48 +661,6 @@ sub getPreOSpkgsList {
|
||||
return (\@selected, \@removed);
|
||||
}
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
=head3 getPreBaseOSpkgsList
|
||||
Get previously selected and removed base OS packages lists from pkglist file. Packages named with "example.xxx" should be the base name "example"
|
||||
|
||||
Arguments:
|
||||
$ospkglist - the path for ospkglist file
|
||||
Returns:
|
||||
refs for selected and removed OS packages arrays
|
||||
Globals:
|
||||
none
|
||||
Error:
|
||||
none
|
||||
Example:
|
||||
my $pre_selected_ref = xCAT::CFMUtils->getPreOSpkgsList($ospkglist);
|
||||
|
||||
=cut
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
sub getPreBaseOSpkgsList {
|
||||
my ($class, $pkglist) = @_;
|
||||
|
||||
my ($pre_selected_ref, $pre_removed_ref) = xCAT::CFMUtils->getPreOSpkgsList($pkglist);
|
||||
|
||||
my %pre_selected_hash = ();
|
||||
foreach (@$pre_selected_ref) {
|
||||
my @names = split(/\./, $_);
|
||||
my $basename = $names[0];
|
||||
|
||||
if ($_ =~ /^$basename\.([^\.]+)$/) {
|
||||
$pre_selected_hash{$basename} = 1;
|
||||
}else {
|
||||
$pre_selected_hash{$_} = 1;
|
||||
}
|
||||
}
|
||||
|
||||
my @pre_selected = keys %pre_selected_hash;
|
||||
|
||||
return \@pre_selected;
|
||||
}
|
||||
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
=head3 getPkgsDiff
|
||||
@@ -879,66 +819,3 @@ sub arrayops {
|
||||
|
||||
#return (\@union, \@intersection, \@difference);
|
||||
}
|
||||
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
=head3 updateSelectedPkgs
|
||||
Update previous selected, previous removed and current selected packages based on fuzzy matching rules. Packages named with "example.i686" should be same with package "example"
|
||||
|
||||
Arguments:
|
||||
\@pre_selected - reference to previous selected packages
|
||||
\@pre_removed - reference to previous removed packages
|
||||
\@cur_selected - reference to current selected packages
|
||||
Returns:
|
||||
new previous selected, previous removed, current selected packages
|
||||
Globals:
|
||||
none
|
||||
Error:
|
||||
none
|
||||
Example:
|
||||
my ($ref1, $ref2, $ref3) = xCAT::CFMUtils->arrayops(\@pre_selected, \@pre_removed, \@cur_selected);
|
||||
|
||||
=cut
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
sub updateSelectedPkgs() {
|
||||
my ($class, $pre_selected_ref, $pre_removed_ref, $cur_selected_ref) = @_;
|
||||
|
||||
my %pre_selected_hash = map{$_ => 1} @$pre_selected_ref;
|
||||
my %pre_removed_hash = map{$_ => 1} @$pre_removed_ref;
|
||||
my %cur_selected_hash = map{$_ => 1} @$cur_selected_ref;
|
||||
|
||||
my %new_pre_selected_hash = %pre_selected_hash;
|
||||
my %new_pre_removed_hash = %pre_removed_hash;
|
||||
my %new_cur_selected_hash = %cur_selected_hash;
|
||||
|
||||
foreach (keys %cur_selected_hash) {
|
||||
my $father = $_;
|
||||
my $flag = 0;
|
||||
foreach (keys %pre_selected_hash) {
|
||||
my $child = $_;
|
||||
if ($child =~ /^$father\.([^\.]+)$/) {
|
||||
$new_cur_selected_hash{$child} = 1;
|
||||
$flag = 1;
|
||||
}
|
||||
}
|
||||
if ($flag and not exists $pre_selected_hash{$father}){
|
||||
delete $new_cur_selected_hash{$father} if exists $new_cur_selected_hash{$father};
|
||||
}
|
||||
|
||||
foreach (keys %pre_removed_hash) {
|
||||
my $child = $_;
|
||||
if ($child =~ /^$father\.([^\.]+)$/) {
|
||||
delete $new_pre_removed_hash{$child} if exists $new_pre_removed_hash{$child};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
my @new_cur_selected = keys %new_cur_selected_hash;
|
||||
my @new_pre_selected = keys %new_pre_selected_hash;
|
||||
my @new_pre_removed = keys %new_pre_removed_hash;
|
||||
|
||||
|
||||
return (\@new_pre_selected, \@new_pre_removed, \@new_cur_selected);
|
||||
}
|
||||
|
||||
+10
-79
@@ -8,11 +8,9 @@ BEGIN
|
||||
|
||||
# if AIX - make sure we include perl 5.8.2 in INC path.
|
||||
# Needed to find perl dependencies shipped in deps tarball.
|
||||
use Storable qw/nstore_fd fd_retrieve/;
|
||||
if ($^O =~ /^aix/i) {
|
||||
unshift(@INC, qw(/usr/opt/perl5/lib/5.8.2/aix-thread-multi /usr/opt/perl5/lib/5.8.2 /usr/opt/perl5/lib/site_perl/5.8.2/aix-thread-multi /usr/opt/perl5/lib/site_perl/5.8.2));
|
||||
}
|
||||
use IO::Handle;
|
||||
|
||||
my $inet6support;
|
||||
if ($^O =~ /^aix/i) { # disable AIX IPV6 TODO fix
|
||||
@@ -29,7 +27,7 @@ if ($inet6support) {
|
||||
|
||||
if ($^O =~ /^linux/i) {
|
||||
# Is IPv6 enabled on the MN or xcat client node at all?
|
||||
my $ipv6enabled = `ip addr 2> /dev/null | grep inet6`;
|
||||
my $ipv6enabled = `ip addr | grep inet6`;
|
||||
if (!$ipv6enabled) {
|
||||
$inet6support = 0;
|
||||
}
|
||||
@@ -79,23 +77,6 @@ sub rspclean {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
sub send_request {
|
||||
my $request = shift;
|
||||
my $sock = shift;
|
||||
my $encode = shift;
|
||||
if ($encode eq "xml") {
|
||||
my $msg=XMLout($request,RootName=>'xcatrequest',NoAttr=>1,KeyAttr=>[]);
|
||||
if ($ENV{XCATXMLTRACE}) { print $msg; }
|
||||
if($ENV{XCATXMLWARNING}) {
|
||||
validateXML($msg);
|
||||
}
|
||||
print $sock $msg;
|
||||
$sock->flush();
|
||||
} else {
|
||||
nstore_fd($request,$sock);
|
||||
$sock->flush();
|
||||
}
|
||||
}
|
||||
#################################
|
||||
# submit_request will take an xCAT command and pass it to the xCAT
|
||||
# server for execution.
|
||||
@@ -242,7 +223,6 @@ if (ref($request) eq 'HASH') { # the request is an array, not pure XML
|
||||
SSL_key_file => $keyfile,
|
||||
SSL_cert_file => $certfile,
|
||||
SSL_ca_file => $cafile,
|
||||
SSL_verify_mode => SSL_VERIFY_PEER,
|
||||
SSL_use_cert => 1,
|
||||
Timeout => 0,
|
||||
);
|
||||
@@ -262,26 +242,20 @@ if (ref($request) eq 'HASH') { # the request is an array, not pure XML
|
||||
}
|
||||
|
||||
my $msg;
|
||||
my $encode = "xml";
|
||||
#storable encoding is unsafe, carry on with the unsafe xml scheme
|
||||
#perhaps one day will support faster schemes
|
||||
#my $encode = "storable";
|
||||
#my $straightprint=0;
|
||||
#if ($ENV{XCATXMLTRACE} or $ENV{XCATXMLWARNING}) { $encode="xml"; }
|
||||
if (ref($request) eq 'HASH') { # the request is an array, not pure XML
|
||||
#print $client "xcatencoding: $encode\n";
|
||||
#my $encok=<$client>;
|
||||
send_request($request,$client,$encode);
|
||||
$msg=XMLout($request,RootName=>'xcatrequest',NoAttr=>1,KeyAttr=>[]);
|
||||
} else { #XML
|
||||
$straightprint=1;
|
||||
$msg=$request;
|
||||
print $client $msg;
|
||||
}
|
||||
$SIG{TERM} = $SIG{INT} = sub { send_request({abortcommand=>[1]},$client,$encode); exit 0; };
|
||||
if ($ENV{XCATXMLTRACE}) { print $msg; }
|
||||
if($ENV{XCATXMLWARNING}) {
|
||||
validateXML($msg);
|
||||
}
|
||||
$SIG{TERM} = $SIG{INT} = sub { print $client XMLout({abortcommand=>1},RootName=>'xcatrequest',NoAttr=>1,KeyAttr=>[]); exit 0; };
|
||||
print $client $msg;
|
||||
my $response;
|
||||
my $rsp;
|
||||
my $cleanexit=0;
|
||||
if ($encode eq 'xml') {
|
||||
my $massresponse="<massresponse>";
|
||||
my $nextcoalescetime=time()+1;
|
||||
my $coalescenow=0;
|
||||
@@ -335,27 +309,6 @@ if (ref($request) eq 'HASH') { # the request is an array, not pure XML
|
||||
$massresponse .= "</massresponse>";
|
||||
$cleanexit = rspclean($massresponse,$callback);
|
||||
}
|
||||
} else { #storable encode
|
||||
my $rsp;
|
||||
eval { $rsp = fd_retrieve($client); };
|
||||
SERVERINPUT: while ($rsp) {
|
||||
my @rsps;
|
||||
if (ref $rsp eq 'ARRAY') {
|
||||
@rsps = @$rsp;
|
||||
} else {
|
||||
@rsps = ($rsp);
|
||||
}
|
||||
foreach (@rsps) {
|
||||
$callback->($_);
|
||||
if ($_->{serverdone}) {
|
||||
$cleanexit=1;
|
||||
last SERVERINPUT;
|
||||
}
|
||||
}
|
||||
$rsp = undef;
|
||||
eval { $rsp = fd_retrieve($client); };
|
||||
}
|
||||
}
|
||||
$massresponse="";
|
||||
unless ($cleanexit) {
|
||||
print STDERR "ERROR/WARNING: communication with the xCAT server seems to have been ended prematurely\n";
|
||||
@@ -1159,12 +1112,7 @@ sub handle_response {
|
||||
#print "printing node\n";
|
||||
my $node;
|
||||
foreach $node (@$nodes) {
|
||||
my $desc;
|
||||
if (ref($node->{name}) eq 'ARRAY') {
|
||||
$desc=$node->{name}->[0];
|
||||
} else {
|
||||
$desc=$node->{name};
|
||||
}
|
||||
my $desc=$node->{name}->[0];
|
||||
if ($node->{errorcode}) {
|
||||
if (ref($node->{errorcode}) eq 'ARRAY') {
|
||||
foreach my $ecode (@{$node->{errorcode}}) {
|
||||
@@ -1184,24 +1132,7 @@ sub handle_response {
|
||||
$errflg=1;
|
||||
}
|
||||
if ($node->{data}) {
|
||||
if (ref(\($node->{data})) eq 'SCALAR') {
|
||||
$desc=$desc.": ".$node->{data};
|
||||
} elsif (ref($node->{data}) eq 'HASH') {
|
||||
if ($node->{data}->{desc}) {
|
||||
if (ref($node->{data}->{desc}) eq 'ARRAY') {
|
||||
$desc=$desc.": ".$node->{data}->{desc}->[0];
|
||||
} else {
|
||||
$desc=$desc.": ".$node->{data}->{desc};
|
||||
}
|
||||
}
|
||||
if ($node->{data}->{contents}) {
|
||||
if (ref($node->{data}->{contents}) eq 'ARRAY') {
|
||||
$desc="$desc: ".$node->{data}->{contents}->[0];
|
||||
} else {
|
||||
$desc="$desc: ".$node->{data}->{contents};
|
||||
}
|
||||
}
|
||||
} elsif (ref(\($node->{data}->[0])) eq 'SCALAR') {
|
||||
if (ref(\($node->{data}->[0])) eq 'SCALAR') {
|
||||
$desc=$desc.": ".$node->{data}->[0];
|
||||
} else {
|
||||
if ($node->{data}->[0]->{desc}) {
|
||||
|
||||
@@ -618,7 +618,7 @@ sub getDBtable
|
||||
{
|
||||
|
||||
# need to get info from DB
|
||||
my $thistable = xCAT::Table->new($table, -create => 1);
|
||||
my $thistable = xCAT::Table->new($table, -create => 1, -autocommit => 0);
|
||||
if (!$thistable)
|
||||
{
|
||||
return undef;
|
||||
@@ -2747,7 +2747,7 @@ sub collapsenicsattr()
|
||||
# e.g nicips.eth0
|
||||
# do not need to handle nic attributes without the postfix .ethx,
|
||||
# it will be overwritten by the attributes with the postfix .ethx,
|
||||
if ($nodeattr =~ /^(nic\w+)\.(.*)$/)
|
||||
if ($nodeattr =~ /^(nic\w+)\.(\w+)$/)
|
||||
{
|
||||
if ($1 && $2)
|
||||
{
|
||||
|
||||
+11
-22
@@ -598,7 +598,7 @@ sub _execute_dsh
|
||||
}
|
||||
else
|
||||
{
|
||||
# HERE: This is where the output shows up
|
||||
# LKV: This is where the output shows up
|
||||
#print STDOUT @{$output_buffers{$user_target}};
|
||||
#print STDERR @{$error_buffers{$user_target}};
|
||||
chomp(@{$output_buffers{$user_target}});
|
||||
@@ -1020,7 +1020,6 @@ sub fork_fanout_dsh
|
||||
}
|
||||
}
|
||||
# save the original exports, we are going to add the unique node name below
|
||||
my $firstpass=0;
|
||||
while (@$targets_waiting
|
||||
&& (keys(%$targets_active) < $$options{'fanout'}))
|
||||
{
|
||||
@@ -1047,7 +1046,6 @@ sub fork_fanout_dsh
|
||||
}
|
||||
if ($$options{'environment'})
|
||||
{
|
||||
if ($firstpass ==0) { # do the servicenode stuff only once
|
||||
# if we are on a servicenode need to get the environment file
|
||||
# from the SNsyncfiledir, not local
|
||||
if (xCAT::Utils->isServiceNode()) {
|
||||
@@ -1070,10 +1068,8 @@ sub fork_fanout_dsh
|
||||
$rsp->{error}->[0] = "File $$options{'environment'} does not exist";
|
||||
xCAT::MsgUtils->message("E", $rsp, $::CALLBACK);
|
||||
}
|
||||
$firstpass=1;
|
||||
}
|
||||
# build the xdsh command
|
||||
push @dsh_command,
|
||||
# build the xdsh command
|
||||
push @dsh_command,
|
||||
"$exportnode$$options{'pre-command'} . $$options{'environment'} ; $$options{'command'}$$options{'post-command'}";
|
||||
}
|
||||
|
||||
@@ -3997,7 +3993,8 @@ sub parse_and_run_dsh
|
||||
{
|
||||
$options{'user'} = $ENV{'DSH_TO_USERID'};
|
||||
}
|
||||
if ((!(defined($nodes))) && (!(defined($options{'rootimg'}))))
|
||||
|
||||
if ((!(defined(@$nodes))) && (!(defined($options{'rootimg'}))))
|
||||
{ # no nodes and not -i option, error
|
||||
my $rsp = ();
|
||||
$rsp->{error}->[0] = "Unless using -i option, noderange is required.";
|
||||
@@ -4036,7 +4033,7 @@ sub parse_and_run_dsh
|
||||
{ # from sinv, discard this name
|
||||
undef @$nodes;
|
||||
}
|
||||
if (@$nodes[0])
|
||||
if (defined(@$nodes))
|
||||
{
|
||||
my $rsp = {};
|
||||
$rsp->{error}->[0] =
|
||||
@@ -4407,16 +4404,8 @@ sub parse_and_run_dcp
|
||||
xCAT::MsgUtils->message("E", $rsp, $::CALLBACK, 1);
|
||||
return;
|
||||
}
|
||||
if (@$nodes[0])
|
||||
{
|
||||
my $rsp = {};
|
||||
$rsp->{error}->[0] =
|
||||
"Input noderange:@$nodes and any other xdsh flags or environment variables are not valid with -i flag.";
|
||||
xCAT::MsgUtils->message("E", $rsp, $::CALLBACK, 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if ((!(defined($nodes))) && (!(defined($options{'rootimg'}))))
|
||||
if ((!(defined(@$nodes))) && (!(defined($options{'rootimg'}))))
|
||||
{ # no nodes and not -i option, error
|
||||
my $rsp = {};
|
||||
$rsp->{error}->[0] = "Unless using -i option, noderange is required.";
|
||||
@@ -4513,7 +4502,7 @@ sub parse_and_run_dcp
|
||||
#
|
||||
# build list of nodes
|
||||
my @nodelist;
|
||||
if (@$nodes[0])
|
||||
if (defined(@$nodes))
|
||||
{ # there are nodes
|
||||
@nodelist = @$nodes;
|
||||
$options{'nodes'} = join(',', @nodelist);
|
||||
@@ -5331,8 +5320,8 @@ sub build_merge_rsync
|
||||
if ($syncmergescript == 0) { # don't add the xdcpmerge.sh line
|
||||
push @::mergelines,$line;
|
||||
}
|
||||
my $src_file = $1; # merge file left of arrow
|
||||
my $orig_src_file = $1;
|
||||
my $src_file = $1; # merge file left of arror
|
||||
my $orig_src_file = $1;
|
||||
# it will be sync'd to $nodesyncfiledir/$merge_file
|
||||
my $dest_file = $nodesyncfiledir;
|
||||
$dest_file .= $src_file;
|
||||
@@ -5361,7 +5350,7 @@ sub build_merge_rsync
|
||||
# to pick up files from /var/xcat/syncfiles...
|
||||
if ($onServiceNode == 1) {
|
||||
my $newsrcfile = $syncdir; # add SN syndir on front
|
||||
$newsrcfile .= $orig_src_file;
|
||||
$newsrcfile .= $orig_src_file;
|
||||
$src_file=$newsrcfile;
|
||||
}
|
||||
# destination file name
|
||||
|
||||
@@ -253,6 +253,64 @@ use strict;
|
||||
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
=head3
|
||||
ifconfig_inet
|
||||
|
||||
Builds a list of all IP Addresses bound to the local host and
|
||||
stores them in a global list
|
||||
|
||||
Arguments:
|
||||
None
|
||||
|
||||
Returns:
|
||||
None
|
||||
|
||||
Globals:
|
||||
@local_inet
|
||||
|
||||
Error:
|
||||
None
|
||||
|
||||
Example:
|
||||
xCAT::DSHCore->ifconfig_inet;
|
||||
|
||||
Comments:
|
||||
Internal routine only
|
||||
|
||||
=cut
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
sub ifconfig_inet
|
||||
{
|
||||
my @local_inet = ();
|
||||
|
||||
if ($^O eq 'aix')
|
||||
{
|
||||
my @ip_address = ();
|
||||
my @output = `/usr/sbin/ifconfig -a`;
|
||||
|
||||
foreach my $line (@output)
|
||||
{
|
||||
($line =~ /inet ((\d{1,3}?\.){3}(\d){1,3})\s/o)
|
||||
&& (push @local_inet, $1);
|
||||
}
|
||||
}
|
||||
|
||||
elsif ($^O eq 'linux')
|
||||
{
|
||||
my @ip_address = ();
|
||||
my @output = `/sbin/ifconfig -a`;
|
||||
|
||||
foreach my $line (@output)
|
||||
{
|
||||
($line =~ /inet addr:((\d{1,3}?\.){3}(\d){1,3})\s/o)
|
||||
&& (push @local_inet, $1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@ sub getHcpAttribs
|
||||
}
|
||||
}
|
||||
|
||||
my @ps = $tabs->{ppc}->getAllNodeAttribs(['node','parent','nodetype','hcp','id']);
|
||||
my @ps = $tabs->{ppc}->getAllNodeAttribs(['node','parent','nodetype','hcp']);
|
||||
for my $entry ( @ps ) {
|
||||
my $tmp_parent = $entry->{parent};
|
||||
my $tmp_node = $entry->{node};
|
||||
@@ -79,9 +79,6 @@ sub getHcpAttribs
|
||||
if (defined($tmp_node) && defined($tmp_type) && ($tmp_type eq "blade") && defined($entry->{hcp})) {
|
||||
push @{$ppchash{$tmp_node}{children}}, $entry->{hcp};
|
||||
}
|
||||
if (defined($tmp_node) && defined($entry->{id}) && defined($tmp_parent) && defined($tmp_type) && ($tmp_type eq "lpar")) {
|
||||
$ppchash{$tmp_parent}{mapping}{$tmp_node} = $entry->{id};
|
||||
}
|
||||
|
||||
#if(exists($ppchash{$tmp_node})) {
|
||||
# if( defined($tmp_type) ) {
|
||||
|
||||
@@ -264,7 +264,7 @@ sub temp {
|
||||
# No frame commands for IVM
|
||||
#################################
|
||||
if ( $hwtype eq "ivm" ) {
|
||||
push @result, [$name,"$prefix Not available (No BPA)",0];
|
||||
push @result, [$name,"$prefix Not available (No BPA)",1];
|
||||
next;
|
||||
}
|
||||
#################################
|
||||
@@ -272,14 +272,14 @@ sub temp {
|
||||
#################################
|
||||
if ( @$d[4] !~ /^(fsp|lpar|cec)$/ ) {
|
||||
my $text = "$prefix Only available for CEC/LPAR";
|
||||
push @result, [$name,$text,0];
|
||||
push @result, [$name,$text,1];
|
||||
next;
|
||||
}
|
||||
#################################
|
||||
# Error - No frame
|
||||
#################################
|
||||
if ( $mtms eq "0" ) {
|
||||
push @result, [$name,"$prefix Not available (No BPA)",0];
|
||||
push @result, [$name,"$prefix Not available (No BPA)",1];
|
||||
next;
|
||||
}
|
||||
#################################
|
||||
@@ -352,7 +352,7 @@ sub rackenv {
|
||||
#################################
|
||||
if ( @$d[4] !~ /^(bpa|frame)$/ ) {
|
||||
my $text = "$prefix Only available for BPA/Frame";
|
||||
push @result, [$name,$text,0];
|
||||
push @result, [$name,$text,1];
|
||||
next;
|
||||
}
|
||||
|
||||
@@ -435,7 +435,7 @@ sub lcds {
|
||||
if( $type eq "lpar" ) {
|
||||
$action = "query_lcds";
|
||||
} elsif ($type eq "blade") {
|
||||
$action = "pblade_query_lcds";
|
||||
$action = "pblade_query_lcds";
|
||||
} else {
|
||||
$action = "cec_query_lcds";
|
||||
}
|
||||
|
||||
+68
-542
@@ -15,8 +15,7 @@ use xCAT::PPCcli qw(SUCCESS EXPECT_ERROR RC_ERROR NR_ERROR);
|
||||
use xCAT::Usage;
|
||||
use xCAT::NodeRange;
|
||||
use xCAT::FSPUtils;
|
||||
use xCAT::VMCommon;
|
||||
use Data::Dumper;
|
||||
#use Data::Dumper;
|
||||
use xCAT::MsgUtils qw(verbose_message);
|
||||
##############################################
|
||||
# Globals
|
||||
@@ -48,26 +47,15 @@ sub parse_args {
|
||||
##########################################################################
|
||||
# Parse the chvm command line for options and operands
|
||||
##########################################################################
|
||||
my @query_array = ();
|
||||
my %param_list_map = (
|
||||
'vmcpus' => 'part_get_lpar_processing',
|
||||
'vmmemory' => 'part_get_lpar_memory',
|
||||
'add_physlots' => 'part_get_all_io_bus_info',
|
||||
'del_physlots' => 'part_get_all_io_bus_info',
|
||||
'add_vmnics' => 'part_get_all_vio_info',
|
||||
'add_vmstorage' => 'part_get_all_vio_info',
|
||||
'del_vadapter' => 'part_get_all_vio_info'
|
||||
);
|
||||
|
||||
sub chvm_parse_extra_options {
|
||||
my $args = shift;
|
||||
my $opt = shift;
|
||||
# Partition used attributes #
|
||||
my @support_ops = qw(vmcpus vmmemory add_physlots vmothersetting add_vmstorage add_vmnics del_vadapter del_physlots);
|
||||
my @support_ops = qw(vmcpus vmmemory vmphyslots vmothersetting);
|
||||
if (ref($args) ne 'ARRAY') {
|
||||
return "$args";
|
||||
}
|
||||
my %tmp_hash = ();
|
||||
foreach (@$args) {
|
||||
my ($cmd, $value) = split (/\=/, $_);
|
||||
if (!defined($value)) {
|
||||
@@ -86,97 +74,16 @@ sub chvm_parse_extra_options {
|
||||
# return "'$value' invalid";
|
||||
# }
|
||||
} elsif (grep(/^$cmd$/, @support_ops)) {
|
||||
if (exists($param_list_map{$cmd})) {
|
||||
$tmp_hash{$param_list_map{$cmd}} = 1;
|
||||
}
|
||||
if (exists($opt->{p775})) {
|
||||
return "'$cmd' doesn't work for Power 775 machines.";
|
||||
} elsif ($cmd eq "del_vadapter") {
|
||||
if ($value !~ /^\d+$/) {
|
||||
return "Invalid param '$value', only one slot id can be specified";
|
||||
}
|
||||
} elsif ($cmd eq "del_physlots") {
|
||||
my @tmp_array = split ",",$value;
|
||||
foreach (@tmp_array) {
|
||||
unless (/(0x\w{8})/) {
|
||||
return "'$_' is invalid";
|
||||
}
|
||||
}
|
||||
} elsif ($cmd eq "vmothersetting") {
|
||||
if ($value =~ /hugepage:\s*(\d+)/i) {
|
||||
$opt->{huge_page} = $1;
|
||||
$tmp_hash{'get_huge_page'} = 1;
|
||||
}
|
||||
if ($value =~ /bsr:\s*(\d+)/i) {
|
||||
$opt->{bsr} = $1;
|
||||
$tmp_hash{'get_cec_bsr'} = 1;
|
||||
}
|
||||
next;
|
||||
} elsif ($cmd eq "add_vmstorage") {
|
||||
if (exists($opt->{vios})) {
|
||||
if ($value !~ /\d+/) {
|
||||
return "'$value' is invalid, must be numbers";
|
||||
} else {
|
||||
my @array = ();
|
||||
for (1..$value) {
|
||||
push @array, 0;
|
||||
}
|
||||
$value = \@array;
|
||||
}
|
||||
} else {
|
||||
if ($value =~ /^([\w_-]*):(\d+)$/) {
|
||||
$value = ["0,$1:$2"];
|
||||
} else {
|
||||
return "'$value' is invalid, must be in form of 'Server_name:slotnum'";
|
||||
}
|
||||
}
|
||||
} elsif ($cmd eq "vmcpus") {
|
||||
if ($value =~ /^(\d+)\/(\d+)\/(\d+)$/) {
|
||||
unless ($1 <= $2 and $2 <= $3) {
|
||||
return "'$value' is invalid, must be in order";
|
||||
}
|
||||
} else {
|
||||
return "'$value' is invalid, must be integer";
|
||||
}
|
||||
} elsif ($cmd eq "vmmemory") {
|
||||
if ($value =~ /^([\d|.]+)([G|M]?)\/([\d|.]+)([G|M]?)\/([\d|.]+)([G|M]?)$/i) {
|
||||
my ($mmin, $mcur, $mmax);
|
||||
if ($2 == "G" or $2 == '') {
|
||||
$mmin = $1 * 1024;
|
||||
}
|
||||
if ($4 == "G" or $4 == '') {
|
||||
$mcur = $3 * 1024;
|
||||
}
|
||||
if ($6 == "G" or $6 == '') {
|
||||
$mmax = $5 * 1024;
|
||||
}
|
||||
unless ($mmin <= $mcur and $mcur <= $mmax) {
|
||||
return "'$value' is invalid, must be in order";
|
||||
}
|
||||
} else {
|
||||
return "'$value' is invalid";
|
||||
}
|
||||
} elsif ($cmd eq "add_physlots") {
|
||||
my @tmp_array = split ",",$value;
|
||||
foreach (@tmp_array) {
|
||||
unless (/(0x\w{8})/) {
|
||||
return "'$_' is invalid";
|
||||
}
|
||||
}
|
||||
} elsif ($cmd eq "vmothersetting") {
|
||||
my @tmp_array = split ",", $value;
|
||||
foreach (@tmp_array) {
|
||||
unless (/^(bsr|hugepage):\d+$/) {
|
||||
return "'$_' is invalid";
|
||||
}
|
||||
}
|
||||
} elsif ($cmd eq "add_vmnics") {
|
||||
my @tmp_array = split ",", $value;
|
||||
foreach (@tmp_array) {
|
||||
unless (/^vlan\d+$/i) {
|
||||
return "'$_' is invalid";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
@@ -184,7 +91,6 @@ sub chvm_parse_extra_options {
|
||||
}
|
||||
$opt->{$cmd} = $value;
|
||||
}
|
||||
@query_array = keys(%tmp_hash);
|
||||
return undef;
|
||||
}
|
||||
|
||||
@@ -218,7 +124,7 @@ sub chvm_parse_args {
|
||||
$Getopt::Long::ignorecase = 0;
|
||||
Getopt::Long::Configure( "bundling" );
|
||||
|
||||
if ( !GetOptions( \%opt, qw(V|verbose p=s i=s m=s r=s p775 vios) )) {
|
||||
if ( !GetOptions( \%opt, qw(V|verbose p=s i=s m=s r=s p775) )) {
|
||||
return( usage() );
|
||||
}
|
||||
####################################
|
||||
@@ -492,7 +398,7 @@ sub mkvm_parse_args {
|
||||
push @unsupport_ops, $tmpop;
|
||||
}
|
||||
}
|
||||
my @support_ops = qw(vmcpus vmmemory vmphyslots vmothersetting vmnics vmstorage);
|
||||
my @support_ops = qw(vmcpus vmmemory vmphyslots vmothersetting);
|
||||
if (defined(@ARGV[0]) and defined($opt{full})) {
|
||||
return(usage("Option 'full' shall be used alone."));
|
||||
} elsif (defined(@ARGV[0])) {
|
||||
@@ -747,7 +653,7 @@ sub lsvm_parse_args {
|
||||
$Getopt::Long::ignorecase = 0;
|
||||
Getopt::Long::Configure( "bundling" );
|
||||
|
||||
if ( !GetOptions( \%opt, qw(V|verbose l|long p775 updatedb) )) {
|
||||
if ( !GetOptions( \%opt, qw(V|verbose l|long p775) )) {
|
||||
return( usage() );
|
||||
}
|
||||
if (exists($opt{l}) && !exists($opt{p775})) {
|
||||
@@ -786,12 +692,11 @@ sub modify {
|
||||
return op_extra_cmds ($request, $hash) if ($request->{opt}->{lparname} || $request->{opt}->{huge_page});
|
||||
return ([["Error", "Miss argument\n".$usage_string, 1]]);
|
||||
}
|
||||
|
||||
sub do_op_extra_cmds {
|
||||
my $request = shift;
|
||||
my $hash = shift;
|
||||
my @values = ();
|
||||
my %lpar_hash = ();
|
||||
|
||||
while (my ($mtms, $h) = each(%$hash)) {
|
||||
my $memhash;
|
||||
while (my($name, $d) = each(%$h)) {
|
||||
@@ -804,47 +709,8 @@ sub do_op_extra_cmds {
|
||||
$action = "set_huge_page";
|
||||
} elsif ($op eq "vmcpus") {
|
||||
$action = "part_set_lpar_pending_proc";
|
||||
} elsif ($op eq "add_physlots" or $op eq "del_physlots") {
|
||||
} elsif ($op eq "vmphyslots") {
|
||||
$action = "set_io_slot_owner_uber";
|
||||
} elsif ($op eq "del_vadapter") {
|
||||
$action = "part_clear_vslot_config";
|
||||
} elsif ($op eq "add_vmnics") {
|
||||
my @vlans = split /,/,$param;
|
||||
foreach (@vlans) {
|
||||
if (/vlan(\d+)/i) {
|
||||
my $vlanid = $1;
|
||||
my $mac = lc(xCAT::VMCommon::genMac($name));
|
||||
if ($mac =~ /(..):(..):(..):(..):(..):(..)/) {
|
||||
my $tail = hex($6)+$vlanid;
|
||||
$mac = sprintf("$1$2$3$4$5%02x",$tail);
|
||||
}
|
||||
my $value = xCAT::FSPUtils::fsp_api_action($request,$name, $d, "part_set_veth_slot_config",0,"0,$vlanid,$mac");
|
||||
if (@$value[1] && ((@$value[1] =~ /Error/i) && (@$value[2] ne '0'))) {
|
||||
return ([[$name, @$value[1], '1']]) ;
|
||||
} else {
|
||||
push @values, [$name, "Success", '0'];
|
||||
}
|
||||
}
|
||||
}
|
||||
next;
|
||||
} elsif ($op eq "add_vmstorage") {
|
||||
foreach my $v_info (@$param) {
|
||||
if ($v_info =~ /(\d+),([\w_-]*):(\d+)/) {
|
||||
my $vios = &find_lpar_id($request, @$d[3], $2);
|
||||
my $r_slotid = $3;
|
||||
if (!defined($vios)) {
|
||||
return ([[$name, "Cannot find lparid for Server lpar:$1", '1']]);
|
||||
}
|
||||
$v_info = "$1,$vios,$r_slotid";
|
||||
}
|
||||
my $value = xCAT::FSPUtils::fsp_api_action($request,$name, $d, "part_set_vscsi_slot_config",0,$v_info);
|
||||
if (@$value[1] && ((@$value[1] =~ /Error/i) && (@$value[2] ne '0'))) {
|
||||
return ([[$name, @$value[1], '1']]) ;
|
||||
} else {
|
||||
push @values, [$name, "Success", '0'];
|
||||
}
|
||||
}
|
||||
next;
|
||||
} elsif ($op eq "vmmemory") {
|
||||
my @td = @$d;
|
||||
@td[0] = 0;
|
||||
@@ -856,17 +722,17 @@ sub do_op_extra_cmds {
|
||||
if ($2 == "G" or $2 == '') {
|
||||
$min = $min * 1024;
|
||||
}
|
||||
$min = int($min/$memsize);
|
||||
$min = $min/$memsize;
|
||||
my $cur = $3;
|
||||
if ($4 == "G" or $4 == '') {
|
||||
$cur = $cur * 1024;
|
||||
}
|
||||
$cur = int($cur/$memsize);
|
||||
$cur = $cur/$memsize;
|
||||
my $max = $5;
|
||||
if ($6 == "G" or $6 == '') {
|
||||
$max = $max * 1024;
|
||||
}
|
||||
$max = int($max/$memsize);
|
||||
$max = $max/$memsize;
|
||||
$request->{opt}->{$op} ="$min/$cur/$max";
|
||||
$param = $request->{opt}->{$op};
|
||||
} else {
|
||||
@@ -878,44 +744,26 @@ sub do_op_extra_cmds {
|
||||
$memhash->{lpar_used_regions} = 0;
|
||||
my $ret = &deal_with_avail_mem($request, $name, $d, $memhash);
|
||||
if (ref($ret) eq "ARRAY") {
|
||||
if (@$ret[2]) {
|
||||
return ([[@$ret]]);
|
||||
} else {
|
||||
push @values, $ret;
|
||||
}
|
||||
return ([[@$ret]]);
|
||||
}
|
||||
$param = $memhash->{memory};
|
||||
$action = "part_set_lpar_pending_mem";
|
||||
} elsif ($op eq "bsr") {
|
||||
$action = "set_lpar_bsr";
|
||||
} elsif ($op eq "vios") {
|
||||
print __LINE__."=========>op=vios===\n";
|
||||
next;
|
||||
} else {
|
||||
last;
|
||||
}
|
||||
my $tmp_value = ($param eq '*') ? $name : $param;
|
||||
xCAT::MsgUtils->verbose_message($request, "$request->{command} $action for node:$name, parm:$tmp_value.");
|
||||
my @tmpd = @$d;
|
||||
if ($op eq "del_physlots") {
|
||||
@tmpd[0] = "-1";
|
||||
}
|
||||
my $value = xCAT::FSPUtils::fsp_api_action($request, $name, \@tmpd, $action, 0, $tmp_value);
|
||||
my $value = xCAT::FSPUtils::fsp_api_action($request, $name, $d, $action, 0, $tmp_value);
|
||||
if (@$value[1] && ((@$value[1] =~ /Error/i) && (@$value[2] ne '0'))) {
|
||||
return ([[$name, @$value[1], '1']]) ;
|
||||
} else {
|
||||
push @values, [$name, "Success", '0'];
|
||||
}
|
||||
}
|
||||
my $rethash = query_cec_info_actions($request, $name, $d, 1, \@query_array);
|
||||
# need to add update db here
|
||||
$lpar_hash{$name} = $rethash;
|
||||
$lpar_hash{$name}->{parent} = @$d[3];
|
||||
}
|
||||
}
|
||||
if (%lpar_hash) {
|
||||
update_vm_db($request, \%lpar_hash);
|
||||
}
|
||||
return \@values;
|
||||
}
|
||||
sub check_node_info {
|
||||
@@ -1696,7 +1544,6 @@ my @partition_query_actions = qw(part_get_partition_cap part_get_hyp_process_and
|
||||
sub parse_part_get_info {
|
||||
my $hash = shift;
|
||||
my $data = shift;
|
||||
my $lparid = shift;
|
||||
my @array = split /\n/, $data;
|
||||
foreach my $line (@array) {
|
||||
chomp($line);
|
||||
@@ -1717,12 +1564,9 @@ sub parse_part_get_info {
|
||||
$hash->{bus}->{$3}->{cur_lparid} = $1;
|
||||
$hash->{bus}->{$3}->{bus_slot} = $2;
|
||||
$hash->{bus}->{$3}->{des} = $4;
|
||||
if ($lparid and $lparid eq $1) {
|
||||
push @{$hash->{lpar_phy_bus}}, $3;
|
||||
}
|
||||
} elsif ($line =~ /Phy drc_index:(\w+), Port group: (\w+), Phy port id: (\w+)/) {
|
||||
$hash->{phy_drc_group_port}->{$1}->{$2}->{$3} = '1';
|
||||
#} elsif ($line =~ /adapter_id=(\w+),lpar_id=([\d|-]+).*port_group=(\d+),phys_port_id=(\d+).*drc_index=(\w+),.*/) {
|
||||
} elsif ($line =~ /adapter_id=(\w+),lpar_id=([\d|-]+).*port_group=(\d+),phys_port_id=(\d+).*drc_index=(\w+),.*/) {
|
||||
if (($2 == -1) && ($4 == 255)) {
|
||||
$hash->{logic_drc_phydrc}->{$3}->{$5} = $1;
|
||||
#$hash->{logic_drc_phydrc}->{$5}->{$1} = [$2,$3,$4];
|
||||
@@ -1735,49 +1579,12 @@ sub parse_part_get_info {
|
||||
$hash->{lpar0_used_mem} = $2;
|
||||
$hash->{phy_min_mem_req} = $3;
|
||||
#print "===>lpar0_used_mem:$hash->{lpar0_used_mem}.\n";
|
||||
} elsif ($line =~ /Curr Memory (Min|Req|Max):\s*([\d]*)[^\(]*\((\d+)\s*regions\)/) {
|
||||
if ($1 eq 'Min') {
|
||||
$hash->{lpar_mem_min} = $2
|
||||
} elsif ($1 eq 'Max') {
|
||||
$hash->{lpar_mem_max} = $2;
|
||||
} else {
|
||||
$hash->{lpar_mem_req} = $2;
|
||||
$hash->{lpar_used_regions} = $3;
|
||||
}
|
||||
} elsif ($line =~ /Curr Processor (Min|Req|Max):\s*(\d+)/) {
|
||||
if ($1 eq 'Min') {
|
||||
$hash->{lpar_cpu_min} = $2;
|
||||
} elsif ($1 eq 'Max') {
|
||||
$hash->{lpar_cpu_max} = $2;
|
||||
} else {
|
||||
$hash->{lpar_cpu_req} = $2;
|
||||
}
|
||||
} elsif ($line =~ /\s*lpar_id=(\d+),type=vSCSI,slot=(\d+),attr=(\d+).*remote_lpar_id=0x(\w+),remote_slot_num=0x(\w+)/) {
|
||||
if ($3 eq '0') {
|
||||
my $lparid = hex($4);
|
||||
my $slotid = hex($5);
|
||||
push @{$hash->{lpar_vmstorage_client}}, "$lparid:$slotid";
|
||||
} else {
|
||||
if (exists($hash->{lpar_vmstorage_server})) {
|
||||
$hash->{lpar_vmstorage_server}++;
|
||||
} else {
|
||||
$hash->{lpar_vmstorage_server} = 1;
|
||||
}
|
||||
}
|
||||
} elsif ($line =~ /\s*lpar_id=(\d+),type=(vEth),slot=(\d+).*port_vlan_id=(\d+),mac_addr=(\w+)/) {
|
||||
push @{$hash->{lpar_vmnics}}, "vlan$4";
|
||||
} elsif ($line =~ /Curr Memory Req:[^\(]*\((\d+)\s*regions\)/) {
|
||||
$hash->{lpar_used_regions} = $1;
|
||||
} elsif ($line =~ /Available huge page memory\(in pages\):\s*(\d+)/) {
|
||||
$hash->{huge_page_avail} = $1;
|
||||
} elsif ($line =~ /Available BSR array:\s*(\d+)/) {
|
||||
$hash->{cec_bsr_avail} = $1;
|
||||
} elsif ($line =~ /^\d+\/(\d+)\/\d+$/) {
|
||||
if ($1 ne 0) {
|
||||
push @{$hash->{lpar_othersetting}}, "hugepage:$1";
|
||||
}
|
||||
} elsif ($line =~ /^(\d+)\.$/) {
|
||||
if ($1 ne 0) {
|
||||
push @{$hash->{lpar_othersetting}}, "bsr:$1";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1788,7 +1595,6 @@ sub query_cec_info_actions {
|
||||
my $td = shift;
|
||||
my $usage = shift;
|
||||
my $action_array = shift;
|
||||
my $lpar_hash = shift;
|
||||
my $lparid = @$td[0];
|
||||
my $data;
|
||||
my @array = ();
|
||||
@@ -1803,16 +1609,12 @@ sub query_cec_info_actions {
|
||||
chomp(@$values[1]);
|
||||
#if ($action eq "part_get_partition_cap" and (@$values[1] =~ /Error:/i or @$values[2] ne 0)) {
|
||||
if (@$values[1] =~ /Error:/i or @$values[2] ne 0) {
|
||||
next; #return ([[@$values]]);
|
||||
return ([[@$values]]);
|
||||
}
|
||||
if (@$values[1] =~ /^$/) {
|
||||
next;
|
||||
}
|
||||
if ($usage eq 1 or $usage eq 2) {
|
||||
&parse_part_get_info(\%hash, @$values[1], $lparid);
|
||||
}
|
||||
|
||||
if ($usage eq 0 or $usage eq 2) {
|
||||
if ($usage eq 0) {
|
||||
if ($lparid) {
|
||||
if ($action eq "lpar_lhea_mac") {
|
||||
my @output = split /\n/,@$values[1];
|
||||
@@ -1836,103 +1638,21 @@ sub query_cec_info_actions {
|
||||
#$data .= "\n";
|
||||
next;
|
||||
}
|
||||
if ($action eq "part_get_all_vio_info") {
|
||||
my @output = split /\n/, @$values[1];
|
||||
my ($drc_index,$drc_name);
|
||||
foreach my $line (@output) {
|
||||
chomp($line);
|
||||
if ($line =~ /Index:.*drc_index:([^,]*),\s*drc_name:(.*)$/) {
|
||||
$drc_index = $1;
|
||||
$drc_name = $2;
|
||||
next;
|
||||
} elsif ($line =~ /\s*lpar_id=(\d+),type=(vSCSI|vSerial),slot=(\d+),attr=(\d+).*remote_lpar_id=(0x\w+),remote_slot_num=(0x\w+)/) {
|
||||
if ($4 eq '0') {
|
||||
push @array, [$name, "$1,$3,$drc_name,$drc_index,$2 Client(Server_lparid=$5,Server_slotid=$6)", 0];
|
||||
} else {
|
||||
push @array, [$name, "$1,$3,$drc_name,$drc_index,$2 Server", 0];
|
||||
}
|
||||
} elsif ($line =~ /\s*lpar_id=(\d+),type=(vEth),slot=(\d+).*port_vlan_id=(\d+),mac_addr=(\w+)/) {
|
||||
push @array, [$name, "$1,$3,$drc_name,$drc_index,$2 (port_vlanid=$4,mac_addr=$5)", 0];
|
||||
#} elsif ($line =~ /\s*lpar_id=(\d+),type=(\w+),slot=(\d+)/) {
|
||||
# push @array, [$name, "$1,$3,$drc_name,$drc_index,$2", 0];
|
||||
#} else {
|
||||
#print "=====>line:$line\n";
|
||||
#push @array, [$name, $line, 0];
|
||||
}
|
||||
$drc_index = '';
|
||||
$drc_name = '';
|
||||
}
|
||||
next;
|
||||
}
|
||||
}
|
||||
#$data .= "@$values[1]\n\n";
|
||||
push @array, [$name, @$values[1], @$values[2]];
|
||||
}
|
||||
}
|
||||
if ($usage eq 0 or $usage eq 2) {
|
||||
#return $data;
|
||||
if ($usage eq 2) {
|
||||
%$lpar_hash = %hash;
|
||||
} else {
|
||||
&parse_part_get_info(\%hash, @$values[1]);
|
||||
}
|
||||
}
|
||||
if ($usage eq 0) {
|
||||
#return $data;
|
||||
return \@array;
|
||||
} else {
|
||||
return \%hash;
|
||||
}
|
||||
}
|
||||
|
||||
sub update_vm_db {
|
||||
my $request = shift;
|
||||
my $lpar_hash = shift;
|
||||
my $vm_hd = xCAT::Table->new('vm');
|
||||
my %name_id_map = ();
|
||||
my $commit = 0;
|
||||
foreach (keys (%$lpar_hash)) {
|
||||
my %db_update = ();
|
||||
my $node_hash = $lpar_hash->{$_};
|
||||
if (exists($node_hash->{lpar_cpu_min})) {
|
||||
$db_update{cpus} = "$node_hash->{lpar_cpu_min}/$node_hash->{lpar_cpu_req}/$node_hash->{lpar_cpu_max}";
|
||||
}
|
||||
if (exists($node_hash->{lpar_mem_min})) {
|
||||
$db_update{memory} = "$node_hash->{lpar_mem_min}/$node_hash->{lpar_mem_req}/$node_hash->{lpar_mem_max}";
|
||||
}
|
||||
if (exists($node_hash->{lpar_vmstorage_server})) {
|
||||
$db_update{storage} = $node_hash->{lpar_vmstorage_server};
|
||||
} elsif (exists($node_hash->{lpar_vmstorage_client})) {
|
||||
my @tmp_array = ();
|
||||
foreach (@{$node_hash->{lpar_vmstorage_client}}) {
|
||||
if (/(\d+):(\d+)/) {
|
||||
if (exists($name_id_map{$1})) {
|
||||
push @tmp_array, "$name_id_map{$1}:$2";
|
||||
} else {
|
||||
my $vios_name = &find_lpar_name($request, $node_hash->{parent}, $1);
|
||||
if (defined($vios_name)) {
|
||||
$name_id_map{$1} = $vios_name;
|
||||
push @tmp_array, "$vios_name:$2";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$db_update{storage} = join(",",@tmp_array);
|
||||
}
|
||||
if (exists($node_hash->{lpar_vmnics})) {
|
||||
$db_update{nics} = join(",",@{$node_hash->{lpar_vmnics}});
|
||||
}
|
||||
if (exists($node_hash->{lpar_phy_bus})) {
|
||||
$db_update{physlots} = join(",",@{$node_hash->{lpar_phy_bus}});
|
||||
}
|
||||
if (exists($node_hash->{lpar_othersetting})) {
|
||||
$db_update{othersettings} = join(",",@{$node_hash->{lpar_othersetting}});
|
||||
}
|
||||
if (%db_update) {
|
||||
$vm_hd->setNodeAttribs($_,\%db_update);
|
||||
$commit = 1;
|
||||
}
|
||||
}
|
||||
if ($commit) {
|
||||
$vm_hd->commit;
|
||||
}
|
||||
}
|
||||
|
||||
#my @partition_query_actions = qw(part_get_partition_cap part_get_num_of_lpar_slots part_get_hyp_config_process_and_mem part_get_hyp_avail_process_and_mem part_get_service_authority_lpar_id part_get_shared_processing_resource part_get_all_vio_info lpar_lhea_mac part_get_all_io_bus_info part_get_lpar_processing part_get_lpar_memory get_huge_page get_cec_bsr);
|
||||
sub query_cec_info {
|
||||
my $request = shift;
|
||||
@@ -1940,36 +1660,23 @@ sub query_cec_info {
|
||||
my $args = $request->{opt};
|
||||
my @td = ();
|
||||
my @result = ();
|
||||
my $usage = 0;
|
||||
my %lpar_hash = ();
|
||||
#print Dumper($request);
|
||||
#print Dumper($hash);
|
||||
while (my ($mtms,$h) = each(%$hash) ) {
|
||||
while (my ($name, $d) = each (%$h)) {
|
||||
my %tmp_hash = ();
|
||||
@td = @$d;
|
||||
if (@$d[0] == 0 && @$d[4] !~ /lpar|vios/) {
|
||||
if (@$d[0] == 0 && @$d[4] ne "lpar") {
|
||||
last;
|
||||
}
|
||||
#my $rethash = query_cec_info_actions($request, $name, $d, 0, ["part_get_lpar_processing","part_get_lpar_memory","part_get_all_vio_info","lpar_lhea_mac","part_get_all_io_bus_info","get_huge_page","get_cec_bsr"]);
|
||||
if ($args->{updatedb}) {
|
||||
$usage = 2;
|
||||
}
|
||||
my $rethash = query_cec_info_actions($request, $name, $d, $usage, ["part_get_lpar_processing","part_get_lpar_memory","part_get_all_io_bus_info","part_get_all_vio_info","get_huge_page","get_cec_bsr"], \%tmp_hash);
|
||||
my $rethash = query_cec_info_actions($request, $name, $d, 0, ["part_get_lpar_processing","part_get_lpar_memory","part_get_all_io_bus_info","get_huge_page","get_cec_bsr"]);
|
||||
#push @result, [$name, $rethash, 0];
|
||||
push @result, @$rethash;
|
||||
$lpar_hash{$name} = \%tmp_hash;
|
||||
$lpar_hash{$name}->{parent} = @$d[3];
|
||||
}
|
||||
if (@td[0] == 0) {
|
||||
my $rethash = query_cec_info_actions($request, @td[3],\@td, $usage);
|
||||
my $rethash = query_cec_info_actions($request, @td[3],\@td, 0);
|
||||
#push @result, [@td[3], $rethash, 0];
|
||||
push @result, @$rethash;
|
||||
}
|
||||
}
|
||||
if ($args->{updatedb} and %lpar_hash) {
|
||||
update_vm_db($request, \%lpar_hash);
|
||||
}
|
||||
return \@result;
|
||||
}
|
||||
|
||||
@@ -2059,17 +1766,13 @@ sub deal_with_avail_mem {
|
||||
} else {
|
||||
$cur_avail = $lparhash->{hyp_avail_mem} + $used_regions - $tmphash{lpar0_used_mem};
|
||||
}
|
||||
#xCAT::MsgUtils->verbose_message($request, "====****====used:$used_regions,avail:$cur_avail,($min:$cur:$max).");
|
||||
xCAT::MsgUtils->verbose_message($request, "====****====used:$used_regions,avail:$cur_avail,($min:$cur:$max).");
|
||||
if ($cur_avail < $min) {
|
||||
my $cur_mem_in_G = $lparhash->{hyp_avail_mem} * $lparhash->{mem_region_size} * 1.0 / 1024;
|
||||
return([$name, "Parse reserverd regions failed, no enough memory, available:$cur_mem_in_G GB.", 1]);
|
||||
return([$name, "Parse reserverd regions failed, no enough memory, available:$lparhash->{hyp_avail_mem}.", 1]);
|
||||
}
|
||||
if (($cur_avail > 0) and ($cur > $cur_avail)) {
|
||||
my $cur_avail_in_G = $cur_avail * $lparhash->{mem_region_size} * 1.0 / 1024;
|
||||
$lparhash->{memory} = "$min/$cur_avail/$max";
|
||||
unless ($lparhash->{full_par}) {
|
||||
return([$name, "Available memory is less than required, allocate $cur_avail_in_G GB.", 0]);
|
||||
}
|
||||
if ($cur > $cur_avail) {
|
||||
my $new_cur = $cur_avail;
|
||||
$lparhash->{memory} = "$min/$new_cur/$max";
|
||||
}
|
||||
} else {
|
||||
return ([$name, "Failed to get hypervisor reserved memory regions.", 1]);
|
||||
@@ -2078,36 +1781,11 @@ sub deal_with_avail_mem {
|
||||
return 0;
|
||||
}
|
||||
|
||||
sub find_lpar_id {
|
||||
my $request = shift;
|
||||
my $parent = shift;
|
||||
my $name = shift;
|
||||
my %mapping = %{$request->{ppc}->{$parent}->{mapping}};
|
||||
if (exists($mapping{$name})) {
|
||||
return $mapping{$name};
|
||||
}
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub find_lpar_name {
|
||||
my $request = shift;
|
||||
my $parent = shift;
|
||||
my $id = shift;
|
||||
my %mapping = %{$request->{ppc}->{$parent}->{mapping}};
|
||||
foreach (keys %mapping) {
|
||||
if ($mapping{$_} eq $id) {
|
||||
return $_;
|
||||
}
|
||||
}
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub create_lpar {
|
||||
my $request = shift;
|
||||
my $name = shift;
|
||||
my $d = shift;
|
||||
my $lparhash = shift;
|
||||
my @ret = ();
|
||||
my $values;
|
||||
if (exists($request->{opt}->{vios})) {
|
||||
$values = xCAT::FSPUtils::fsp_api_action($request, $name, $d, "part_set_lpar_def_state", 0, 0x03);
|
||||
@@ -2120,48 +1798,18 @@ sub create_lpar {
|
||||
$values = xCAT::FSPUtils::fsp_api_action($request, $name, $d, "set_lpar_name", 0, $name);
|
||||
if (@$values[2] ne 0) {
|
||||
&set_lpar_undefined($request, $name, $d);
|
||||
return ([[$name, @$values[1], @$values[0]]]);
|
||||
return ([$name, @$values[1], @$values[0]]);
|
||||
}
|
||||
xCAT::FSPUtils::fsp_api_action($request, $name, $d, "part_set_lpar_shared_pool_util_auth");
|
||||
xCAT::FSPUtils::fsp_api_action($request, $name, $d, "part_set_lpar_group_id");
|
||||
xCAT::FSPUtils::fsp_api_action($request, $name, $d, "part_set_lpar_avail_priority");
|
||||
#print "======>physlots:$lparhash->{physlots}.\n";
|
||||
if (exists($lparhash->{physlots})) {
|
||||
$values = xCAT::FSPUtils::fsp_api_action($request, $name, $d, "set_io_slot_owner_uber", 0, $lparhash->{physlots});
|
||||
#$values = xCAT::FSPUtils::fsp_api_action($request, $name, $d, "set_io_slot_owner", 0, join(",",@phy_io_array));
|
||||
if (@$values[2] ne 0) {
|
||||
&set_lpar_undefined($request, $name, $d);
|
||||
return ([[$name, @$values[1], @$values[2]]]);
|
||||
}
|
||||
$values = xCAT::FSPUtils::fsp_api_action($request, $name, $d, "set_io_slot_owner_uber", 0, $lparhash->{physlots});
|
||||
#$values = xCAT::FSPUtils::fsp_api_action($request, $name, $d, "set_io_slot_owner", 0, join(",",@phy_io_array));
|
||||
if (@$values[2] ne 0) {
|
||||
&set_lpar_undefined($request, $name, $d);
|
||||
return ([$name, @$values[1], @$values[2]]);
|
||||
}
|
||||
if (exists($lparhash->{nics})) {
|
||||
my @vlans = split /,/,$lparhash->{nics};
|
||||
foreach (@vlans) {
|
||||
if (/vlan(\d+)/i) {
|
||||
my $vlanid = $1;
|
||||
my $mac = lc(xCAT::VMCommon::genMac($name));
|
||||
if ($mac =~ /(..):(..):(..):(..):(..):(..)/) {
|
||||
my $tail = hex($6)+$vlanid;
|
||||
$mac = sprintf("$1$2$3$4$5%02x",$tail);
|
||||
}
|
||||
$values = xCAT::FSPUtils::fsp_api_action($request,$name, $d, "part_set_veth_slot_config",0,"0,$vlanid,$mac");
|
||||
if (@$values[2] ne 0) {
|
||||
&set_lpar_undefined($request, $name, $d);
|
||||
return ([[$name, @$values[1], @$values[2]]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (exists($lparhash->{storage})) {
|
||||
foreach my $v_info (@{$lparhash->{storage}}) {
|
||||
$values = xCAT::FSPUtils::fsp_api_action($request,$name, $d, "part_set_vscsi_slot_config",0,$v_info);
|
||||
if (@$values[2] ne 0) {
|
||||
&set_lpar_undefined($request, $name, $d);
|
||||
return ([[$name, @$values[1], @$values[2]]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
# ====== ====== #
|
||||
if (exists($lparhash->{phy_hea})) {
|
||||
my $phy_hash = $lparhash->{phy_hea};
|
||||
foreach my $phy_drc (keys %$phy_hash) {
|
||||
@@ -2188,25 +1836,20 @@ sub create_lpar {
|
||||
$values = xCAT::FSPUtils::fsp_api_action($request, $name, $d, "part_set_lpar_pending_proc", 0, $lparhash->{cpus});
|
||||
if (@$values[2] ne 0) {
|
||||
&set_lpar_undefined($request, $name, $d);
|
||||
return ([[$name, @$values[1], @$values[2]]]);
|
||||
return ([$name, @$values[1], @$values[2]]);
|
||||
}
|
||||
$values = &deal_with_avail_mem($request, $name, $d,$lparhash);
|
||||
if (ref($values) eq "ARRAY") {
|
||||
if (@$values[2]) {
|
||||
&set_lpar_undefined($request, $name, $d);
|
||||
return ([[@$values]]);
|
||||
} else {
|
||||
push @ret, $values;
|
||||
}
|
||||
&set_lpar_undefined($request, $name, $d);
|
||||
return ([@$values]);
|
||||
}
|
||||
|
||||
#print "======>memory:$lparhash->{memory}.\n";
|
||||
$values = xCAT::FSPUtils::fsp_api_action($request, $name, $d, "part_set_lpar_pending_mem", 0, $lparhash->{memory});
|
||||
if (@$values[2] ne 0) {
|
||||
&set_lpar_undefined($request, $name, $d);
|
||||
return ([[$name, @$values[1], @$values[2]]]);
|
||||
return ([$name, @$values[1], @$values[2]]);
|
||||
}
|
||||
|
||||
xCAT::FSPUtils::fsp_api_action($request, $name, $d, "part_set_lpar_comp_modes");
|
||||
#print "======>memory:$lparhash->{huge_page}.\n";
|
||||
xCAT::FSPUtils::fsp_api_action($request, $name, $d, "set_huge_page", 0, $lparhash->{huge_page});
|
||||
@@ -2219,11 +1862,9 @@ sub create_lpar {
|
||||
$values = xCAT::FSPUtils::fsp_api_action($request, $name, $d, "part_set_lpar_def_state", 0, 0x02);
|
||||
}
|
||||
if (@$values[2] ne 0) {
|
||||
return ([[$name, @$values[1], @$values[2]]]);
|
||||
return ([$name, @$values[1], @$values[2]]);
|
||||
}
|
||||
push @ret, [$name, "Done", 0];
|
||||
#return ([$name, "Done", 0]);
|
||||
return \@ret;
|
||||
return ([$name, "Done", 0]);
|
||||
}
|
||||
|
||||
sub mkspeclpar {
|
||||
@@ -2232,7 +1873,6 @@ sub mkspeclpar {
|
||||
my $opt = $request->{opt};
|
||||
my $values;
|
||||
my @result = ();
|
||||
my %lpar_hash = ();
|
||||
my $vmtab = xCAT::Table->new( 'vm');
|
||||
unless($vmtab) {
|
||||
return([["Error","Cannot open vm table", 1]]);
|
||||
@@ -2240,18 +1880,17 @@ sub mkspeclpar {
|
||||
while (my ($mtms, $h) = each (%$hash)) {
|
||||
my $memhash;
|
||||
my @nodes = keys(%$h);
|
||||
my $ent = $vmtab->getNodesAttribs(\@nodes, ['cpus', 'memory','physlots', 'othersettings', 'storage', 'nics']);
|
||||
my $ent = $vmtab->getNodesAttribs(\@nodes, ['cpus', 'memory','physlots', 'othersettings']);
|
||||
while (my ($name, $d) = each (%$h)) {
|
||||
if (@$d[4] ne 'lpar') {
|
||||
push @result, [$name, "Node must be LPAR", 1];
|
||||
last;
|
||||
}
|
||||
#if (!exists($memhash->{run}))
|
||||
{
|
||||
if (!exists($memhash->{run})) {
|
||||
my @td = @$d;
|
||||
@td[0] = 0;
|
||||
$memhash = &query_cec_info_actions($request, $name, \@td, 1, ["part_get_hyp_process_and_mem","lpar_lhea_mac","part_get_all_io_bus_info"]);
|
||||
#$memhash->{run} = 1;
|
||||
$memhash = &query_cec_info_actions($request, $name, \@td, 1, ["part_get_hyp_process_and_mem","lpar_lhea_mac"]);
|
||||
$memhash->{run} = 1;
|
||||
}
|
||||
my $tmp_ent = $ent->{$name}->[0];
|
||||
if (exists($opt->{vmcpus})) {
|
||||
@@ -2263,166 +1902,55 @@ sub mkspeclpar {
|
||||
if (exists($opt->{vmphyslots})) {
|
||||
$tmp_ent->{physlots} = $opt->{vmphyslots};
|
||||
}
|
||||
|
||||
if (exists($opt->{vmothersetting})) {
|
||||
$tmp_ent->{othersettings} = $opt->{vmothersetting};
|
||||
}
|
||||
if (exists($opt->{vmstorage})) {
|
||||
$tmp_ent->{storage} = $opt->{vmstorage};
|
||||
}
|
||||
if (exists($opt->{vmnics})) {
|
||||
$tmp_ent->{nics} = $opt->{vmnics};
|
||||
}
|
||||
|
||||
|
||||
if (!defined($tmp_ent) ) {
|
||||
return ([[$name, "Not find params", 1]]);
|
||||
#} elsif (!exists($tmp_ent->{cpus}) || !exists($tmp_ent->{memory}) || !exists($tmp_ent->{physlots})) {
|
||||
} elsif (!exists($tmp_ent->{cpus}) || !exists($tmp_ent->{memory})) {
|
||||
return ([[$name, "The attribute 'vmcpus', 'vmmemory' are needed to be specified.", 1]]);
|
||||
} elsif (!exists($tmp_ent->{cpus}) || !exists($tmp_ent->{memory}) || !exists($tmp_ent->{physlots})) {
|
||||
return ([[$name, "The attribute 'vmcpus', 'vmmemory' and 'vmphyslots' are all needed to be specified.", 1]]);
|
||||
}
|
||||
# FIX bug 3873 [FVT]DFM illegal action could work
|
||||
#
|
||||
|
||||
if ($tmp_ent->{cpus} =~ /^(\d+)\/(\d+)\/(\d+)$/) {
|
||||
unless ($1 <= $2 and $2 <= $3) {
|
||||
return([[$name, "Parameter for 'vmcpus' is invalid", 1]]);
|
||||
} elsif ($memhash->{process_units_avail} eq '0') {
|
||||
push @result, [$name, "No process available", 1];
|
||||
next;
|
||||
} elsif ($2 > $memhash->{process_units_avail}) {
|
||||
my $cur = $memhash->{process_units_avail};
|
||||
my $min = $1 > $cur ? $cur : $1;
|
||||
$tmp_ent->{cpus} = "$min/$cur/$3";
|
||||
push @result, [$name, "Available processor is less than required, allocate $cur processors.", 0];
|
||||
}
|
||||
} else {
|
||||
return([[$name, "Parameter for 'vmcpus' is invalid", 1]]);
|
||||
}
|
||||
if ($tmp_ent->{memory} =~ /^([\d|.]+)([G|M]?)\/([\d|.]+)([G|M]?)\/([\d|.]+)([G|M]?)$/i) {
|
||||
if ($memhash->{hyp_avail_mem} eq '0') {
|
||||
push @result, [$name, "No memory available", 1];
|
||||
next;
|
||||
}
|
||||
my ($mmin, $mcur, $mmax);
|
||||
if ($2 == "G" or $2 == '') {
|
||||
$mmin = $1 * 1024;
|
||||
}
|
||||
if ($4 == "G" or $4 == '') {
|
||||
$mcur = $3 * 1024;
|
||||
}
|
||||
if ($6 == "G" or $6 == '') {
|
||||
$mmax = $5 * 1024;
|
||||
}
|
||||
unless ($mmin <= $mcur and $mcur <= $mmax) {
|
||||
return([[$name, "Parameter for 'vmmemory' is invalid", 1]]);
|
||||
}
|
||||
if ($tmp_ent->{memory} =~ /(\d+)([G|M]?)\/(\d+)([G|M]?)\/(\d+)([G|M]?)/i) {
|
||||
my $memsize = $memhash->{mem_region_size};
|
||||
$mmin = int(($mmin + $memsize - 1) / $memsize);
|
||||
$mcur = int(($mcur + $memsize - 1) / $memsize);
|
||||
$mmax = int(($mmax + $memsize - 1) / $memsize);
|
||||
$tmp_ent->{memory} = "$mmin/$mcur/$mmax";
|
||||
$tmp_ent->{mem_region_size} = $memsize;
|
||||
} else {
|
||||
return([[$name, "Parameter for 'vmmemory' is invalid", 1]]);
|
||||
}
|
||||
|
||||
if (exists($tmp_ent->{physlots})) {
|
||||
my @tmp_array = split ",",$tmp_ent->{physlots};
|
||||
foreach (@tmp_array) {
|
||||
unless (/(0x\w{8})/i) {
|
||||
return([[$name, "Parameter:$_ for 'vmphyslots' is invalid", 1]]);
|
||||
}
|
||||
my $min = $1;
|
||||
if ($2 == "G" or $2 == '') {
|
||||
$min = $min * 1024;
|
||||
}
|
||||
}
|
||||
if (exists($tmp_ent->{othersettings})) {
|
||||
my @tmp_array = split ",",$tmp_ent->{othersettings};
|
||||
foreach (@tmp_array) {
|
||||
unless (/^(bsr|hugepage):\d+$/) {
|
||||
return([[$name, "Parameter:$_ for 'vmothersetting' is invalid", 1]]);
|
||||
}
|
||||
$min = $min/$memsize;
|
||||
my $cur = $3;
|
||||
if ($4 == "G" or $4 == '') {
|
||||
$cur = $cur * 1024;
|
||||
}
|
||||
}
|
||||
|
||||
if (exists($tmp_ent->{nics})) {
|
||||
my @tmp_array = split ",",$tmp_ent->{nics};
|
||||
foreach (@tmp_array) {
|
||||
unless (/^vlan\d+$/i) {
|
||||
return([[$name, "Parameter:$_ for 'vmnics' is invalid", 1]]);
|
||||
}
|
||||
$cur = $cur/$memsize;
|
||||
my $max = $5;
|
||||
if ($6 == "G" or $6 == '') {
|
||||
$max = $max * 1024;
|
||||
}
|
||||
$max = $max/$memsize;
|
||||
$tmp_ent->{memory} = "$min/$cur/$max";
|
||||
}
|
||||
|
||||
|
||||
if (exists($opt->{vios})) {
|
||||
if (!exists($tmp_ent->{physlots})) {
|
||||
my @phy_io_array = keys(%{$memhash->{bus}});
|
||||
$tmp_ent->{physlots} = join(",", @phy_io_array);
|
||||
}
|
||||
if (exists($tmp_ent->{storage}) and $tmp_ent->{storage} !~ /^\d+$/) {
|
||||
return ([[$name, "Parameter for 'vmstorage' is invalid", 1]]);
|
||||
} elsif (exists($tmp_ent->{storage})) {
|
||||
my $num = $tmp_ent->{storage};
|
||||
my @array = ();
|
||||
for (1..$num) {
|
||||
push @array, '0';
|
||||
}
|
||||
$tmp_ent->{storage} = \@array;
|
||||
}
|
||||
} else {
|
||||
if (exists($tmp_ent->{storage})) {
|
||||
my @tmp_array = split ",",$tmp_ent->{storage};
|
||||
my $storage_array = undef;
|
||||
foreach (@tmp_array) {
|
||||
if (/([\w_-]*):(\d+)/) {
|
||||
my $vios = &find_lpar_id($request, @$d[3], $1);
|
||||
my $r_slotid = $2;
|
||||
if (defined($vios)) {
|
||||
push @$storage_array, "0,$vios,$r_slotid";
|
||||
} else {
|
||||
return ([[$name, "Cannot find lparid for Server lpar:$1"]]);
|
||||
}
|
||||
} else {
|
||||
return ([[$name, "Parameter for 'vmstorage' is invalid", 1]]);
|
||||
}
|
||||
}
|
||||
$tmp_ent->{storage} = $storage_array;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
$tmp_ent->{hyp_config_mem} = $memhash->{hyp_config_mem};
|
||||
$tmp_ent->{hyp_avail_mem} = $memhash->{hyp_avail_mem};
|
||||
$tmp_ent->{huge_page} = "0/0/0";
|
||||
$tmp_ent->{bsr_num} = "0";
|
||||
if (exists($tmp_ent->{othersettings})) {
|
||||
my $setting = $tmp_ent->{othersettings};
|
||||
if ($setting =~ /hugepage:(\d+)/) {
|
||||
my $tmp = $1;
|
||||
if ($tmp >= 1) {
|
||||
$tmp_ent->{huge_page} = "1/".$tmp."/".$tmp;
|
||||
}
|
||||
$tmp_ent->{huge_page} = "1/".$tmp."/".$tmp;
|
||||
}
|
||||
if ($setting =~ /bsr:(\d+)/) {
|
||||
if ($1 >= 1) {
|
||||
$tmp_ent->{bsr_num} = $1;
|
||||
}
|
||||
$tmp_ent->{bsr_num} = $1;
|
||||
}
|
||||
}
|
||||
$tmp_ent->{phy_hea} = $memhash->{phy_drc_group_port};
|
||||
$tmp_ent->{logic_drc_phydrc} = $memhash->{logic_drc_phydrc};
|
||||
$values = &create_lpar($request, $name, $d, $tmp_ent);
|
||||
push @result, @$values;
|
||||
#need to add update db here
|
||||
my $rethash = query_cec_info_actions($request, $name, $d, 1, ["part_get_lpar_processing","part_get_lpar_memory","part_get_all_vio_info","part_get_all_io_bus_info","get_huge_page","get_cec_bsr"]);
|
||||
$lpar_hash{$name} = $rethash;
|
||||
$lpar_hash{$name}->{parent} = @$d[3];
|
||||
|
||||
push @result, $values;
|
||||
$name = undef;
|
||||
$d = undef;
|
||||
}
|
||||
}
|
||||
if (%lpar_hash) {
|
||||
update_vm_db($request, \%lpar_hash);
|
||||
}
|
||||
return \@result;
|
||||
}
|
||||
|
||||
@@ -2453,17 +1981,15 @@ sub mkfulllpar {
|
||||
$lpar_param{memory} = "1/".$rethash->{hyp_avail_mem}."/".$rethash->{hyp_config_mem};
|
||||
$lpar_param{hyp_config_mem} = $rethash->{hyp_config_mem};
|
||||
$lpar_param{hyp_avail_mem} = $rethash->{hyp_avail_mem};
|
||||
$lpar_param{mem_region_size} = $rethash->{mem_region_size};
|
||||
my @phy_io_array = keys(%{$rethash->{bus}});
|
||||
$lpar_param{physlots} = join(",", @phy_io_array);
|
||||
$lpar_param{huge_page} = "1/".$rethash->{huge_page_avail}."/".$rethash->{huge_page_avail};
|
||||
$lpar_param{bsr_num} = $rethash->{cec_bsr_avail};
|
||||
$lpar_param{phy_hea} = $rethash->{phy_drc_group_port};
|
||||
$lpar_param{logic_drc_phydrc} = $rethash->{logic_drc_phydrc};
|
||||
$lpar_param{full_par} = 1;
|
||||
$values = &create_lpar($request, $name, $d, \%lpar_param);
|
||||
$rethash->{logic_drc_phydrc} = $lpar_param{logic_drc_phydrc};
|
||||
push @result, @$values;
|
||||
push @result, $values;
|
||||
$name = undef;
|
||||
$d = undef;
|
||||
}
|
||||
|
||||
@@ -56,7 +56,6 @@ $::STATUS_SHELL="shell";
|
||||
$::STATUS_DEFINED="defined";
|
||||
$::STATUS_UNKNOWN="unknown";
|
||||
$::STATUS_FAILED="failed";
|
||||
$::STATUS_BMCREADY="bmcready";
|
||||
%::VALID_STATUS_VALUES = (
|
||||
$::STATUS_ACTIVE=>1,
|
||||
$::STATUS_INACTIVE=>1,
|
||||
@@ -73,7 +72,6 @@ $::STATUS_BMCREADY="bmcready";
|
||||
$::STATUS_DEFINED=>1,
|
||||
$::STATUS_UNKNOWN=>1,
|
||||
$::STATUS_FAILED=>1,
|
||||
$::STATUS_BMCREADY=>1,
|
||||
|
||||
$::STATUS_SYNCING=>1,
|
||||
$::STATUS_OUT_OF_SYNC=>1,
|
||||
|
||||
Executable → Regular
+8
-26
@@ -217,23 +217,14 @@ sub is_me
|
||||
#my ($b1, $b2, $b3, $b4) = split /\./, $nameIP;
|
||||
|
||||
# get all the possible IPs for the node I'm running on
|
||||
# this is a common subroutine for both AIX and Linux,
|
||||
# AIX does not have ip command
|
||||
my $ipcmd;
|
||||
if ( -f "/sbin/ip" )
|
||||
{
|
||||
$ipcmd = "ip addr | grep 'inet'";
|
||||
}
|
||||
else
|
||||
{
|
||||
$ipcmd = "ifconfig -a | grep 'inet'";
|
||||
}
|
||||
my $result = xCAT::Utils->runcmd($ipcmd, -1, 1);
|
||||
my $ifcmd = "ifconfig -a | grep 'inet'";
|
||||
my $result = xCAT::Utils->runcmd($ifcmd, -1, 1);
|
||||
if ($::RUNCMD_RC != 0)
|
||||
{
|
||||
my $str="Error running ipcmd";
|
||||
xCAT::MsgUtils->message("S", $str);
|
||||
$::VERBOSE = $verb;
|
||||
my $rsp;
|
||||
# push @{$rsp->{data}}, "Could not run $ifcmd.\n";
|
||||
# xCAT::MsgUtils->message("E", $rsp, $callback);
|
||||
$::VERBOSE = $verb;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -241,6 +232,7 @@ sub is_me
|
||||
{
|
||||
my ($inet, $myIP, $str) = split(" ", $int);
|
||||
chomp $myIP;
|
||||
$myIP =~ s/addr://;
|
||||
$myIP =~ s/\/.*//; # ipv6 address 4000::99/64
|
||||
$myIP =~ s/\%.*//; # ipv6 address ::1%1/128
|
||||
|
||||
@@ -1031,7 +1023,7 @@ sub dolitesetup
|
||||
$nrange = join(',',@nodel);
|
||||
}
|
||||
|
||||
@flist = xCAT::Utils->runcmd("/opt/xcat/bin/litefile $nrange", -1);
|
||||
my @flist = xCAT::Utils->runcmd("/opt/xcat/bin/litefile $nrange", -1);
|
||||
if (scalar(@flist) > 0) {
|
||||
foreach my $l (@flist) {
|
||||
my ($j1, $j2, $file) = split /\s+/, $l;
|
||||
@@ -1361,16 +1353,6 @@ sub dolitesetup
|
||||
return 1;
|
||||
}
|
||||
|
||||
# also copy $instrootloc/.statelite contents
|
||||
$ccmd = "/usr/bin/cp -p -r $instrootloc/.statelite $SRloc";
|
||||
$out = xCAT::Utils->runcmd("$ccmd", -1);
|
||||
if ($::RUNCMD_RC != 0)
|
||||
{
|
||||
my $rsp;
|
||||
push @{$rsp->{data}}, "Could not copy $instrootloc/.statelite to $SRloc.";
|
||||
xCAT::MsgUtils->message("E", $rsp, $callback);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Executable → Regular
+12
-60
@@ -827,7 +827,7 @@ sub get_mac_addr {
|
||||
$done[0] = 0;
|
||||
$cmd[0] = "\" local-mac-address\" ". $phandle . " get-package-property\r";
|
||||
$msg[0] = "Status: return code and mac-address now on stack\n";
|
||||
$pattern[0] = "local-mac-address.*ok";#"\s*3 >";
|
||||
$pattern[0] = "ok";#"\s*3 >";
|
||||
$newstate[0] = 1;
|
||||
|
||||
# cmd(1) is a dot (.). This is a stack manipulation command that removes one
|
||||
@@ -1231,8 +1231,8 @@ sub ping_server{
|
||||
$done[2] = 0;
|
||||
$cmd[2] = "dev /packages/net\r";
|
||||
$msg[2] = "Status: selected the /packages/net node as the active package\n";
|
||||
$pattern[2] = ".*dev.*packages.*net(.*)ok(.*)0 >(.*)";
|
||||
#$pattern[2] = "ok";
|
||||
#$pattern[2] = ".*dev(.*)ok(.*)0 >(.*)";
|
||||
$pattern[2] = "ok";
|
||||
$newstate[2]= 3;
|
||||
|
||||
# state 3, ping the server
|
||||
@@ -1240,12 +1240,6 @@ sub ping_server{
|
||||
$msg[3] = "Status: ping return code now on stack\n";
|
||||
$newstate[3] = 4;
|
||||
|
||||
# get the timeout for ping test
|
||||
my $to4pt;
|
||||
if ( $ENV{TIMEOUT4PINGTEST} =~ /^\d+$/ ) {
|
||||
$to4pt = ",$ENV{TIMEOUT4PINGTEST}";
|
||||
}
|
||||
|
||||
#IPv6
|
||||
if ( $server_ip =~ /:/ ) {
|
||||
#::1, calculate link local address
|
||||
@@ -1255,9 +1249,9 @@ sub ping_server{
|
||||
} else {
|
||||
$linklocal_ip = $client_ip;
|
||||
}
|
||||
$cmd[3] = "ping $full_path_name:ipv6,$server_ip,$linklocal_ip,$gateway_ip$to4pt\r";
|
||||
$cmd[3] = "ping $full_path_name:ipv6,$server_ip,$linklocal_ip,$gateway_ip\r";
|
||||
} else {
|
||||
$cmd[3] = "ping $full_path_name:$server_ip,$client_ip,$gateway_ip$to4pt\r";
|
||||
$cmd[3] = "ping $full_path_name:$server_ip,$client_ip,$gateway_ip\r";
|
||||
}
|
||||
$pattern[3] = ".*ping(.*)ok(.*)0 >(.*)";
|
||||
|
||||
@@ -1272,7 +1266,6 @@ sub ping_server{
|
||||
# state 5, all done
|
||||
$done[5] = 1;
|
||||
|
||||
|
||||
# for ping, only need to set speed and duplex for ethernet adapters
|
||||
#
|
||||
if ( $list_type eq "ent" ) {
|
||||
@@ -1330,10 +1323,8 @@ sub ping_server{
|
||||
|
||||
$timeout = 300;
|
||||
while ( $done[$state] eq 0 ) {
|
||||
|
||||
send_command($verbose, $rconsole, $cmd[$state]);
|
||||
@result = $rconsole->expect(
|
||||
|
||||
$timeout,
|
||||
[qr/$pattern[$state]/s=>
|
||||
sub {
|
||||
@@ -1371,9 +1362,7 @@ sub ping_server{
|
||||
}
|
||||
],
|
||||
);
|
||||
|
||||
return 1 if ($rc eq 1);
|
||||
|
||||
return 1 if ($rc eq 1);
|
||||
if ( $state eq 1 ) {
|
||||
$adap_conn = $adap_conn_list[$j];
|
||||
$cmd[1] = "\" ethernet,$adap_speed,$adap_conn,$adap_duplex\" encode-string \" chosen-network-type\" property\r";
|
||||
@@ -2061,46 +2050,14 @@ sub multiple_open_dev {
|
||||
; \r";
|
||||
send_command($verbose, $rconsole, $command);
|
||||
|
||||
$timeout = 30;
|
||||
$rconsole->expect(
|
||||
$timeout,
|
||||
[qr/new-open-dev(.*)ok/=>
|
||||
#[qr/>/=>
|
||||
sub {
|
||||
nc_msg($verbose, "Status: at End of multiple_open_dev \n");
|
||||
$rconsole->clear_accum();
|
||||
}
|
||||
],
|
||||
[qr/]/=>
|
||||
sub {
|
||||
nc_msg($verbose, "Unexpected prompt\n");
|
||||
$rconsole->clear_accum();
|
||||
$rc = 1;
|
||||
}
|
||||
],
|
||||
[timeout =>
|
||||
sub {
|
||||
send_user(2, "Timeout\n");
|
||||
$rconsole->clear_accum();
|
||||
$rc = 1;
|
||||
}
|
||||
],
|
||||
[eof =>
|
||||
sub {
|
||||
send_user(2, "Cannot connect to $node\n");
|
||||
$rconsole->clear_accum();
|
||||
$rc = 1;
|
||||
}
|
||||
],
|
||||
);
|
||||
|
||||
$command = "patch new-open-dev open-dev net-ping \r";
|
||||
send_command($verbose, $rconsole, $command);
|
||||
|
||||
$timeout = 30;
|
||||
$rconsole->expect(
|
||||
$timeout,
|
||||
[qr/patch new-open-dev(.*)ok/=>
|
||||
#[qr/>/=>
|
||||
#[qr/patch new-open-dev(.*)>/=>
|
||||
[qr/>/=>
|
||||
sub {
|
||||
nc_msg($verbose, "Status: at End of multiple_open_dev \n");
|
||||
$rconsole->clear_accum();
|
||||
@@ -2129,7 +2086,6 @@ sub multiple_open_dev {
|
||||
}
|
||||
],
|
||||
);
|
||||
|
||||
return $rc;
|
||||
}
|
||||
###################################################################
|
||||
@@ -2613,7 +2569,7 @@ sub lparnetbootexp
|
||||
####################################
|
||||
nc_msg($verbose, "Connecting to the $node.\n");
|
||||
sleep 3;
|
||||
$timeout = 10;
|
||||
$timeout = 2;
|
||||
$rconsole->expect(
|
||||
$timeout,
|
||||
[ qr/Enter.* for help.*/i =>
|
||||
@@ -2634,7 +2590,7 @@ sub lparnetbootexp
|
||||
sub {
|
||||
$rc = 2;
|
||||
$rconsole->clear_accum();
|
||||
nc_msg(1, "Please make sure rcons $node works.\n");
|
||||
nc_msg($verbose, "Please make sure rcons $node works.\n");
|
||||
}
|
||||
],
|
||||
);
|
||||
@@ -2822,8 +2778,6 @@ sub lparnetbootexp
|
||||
$done = 0;
|
||||
$retry_count = 0;
|
||||
|
||||
$timeout = 10;
|
||||
|
||||
while (!$done) {
|
||||
my @result = $rconsole->expect(
|
||||
$timeout,
|
||||
@@ -2931,7 +2885,6 @@ sub lparnetbootexp
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
##############################
|
||||
# Call multiple_open_dev to
|
||||
# circumvent firmware OPEN-DEV
|
||||
@@ -2966,7 +2919,6 @@ sub lparnetbootexp
|
||||
$match_pat = ".*";
|
||||
}
|
||||
|
||||
|
||||
if($colon) {
|
||||
nc_msg($verbose, "#Type:Location_Code:MAC_Address:Full_Path_Name:Ping_Result:Device_Type:Size_MB:OS:OS_Version:\n");
|
||||
$outputarrayindex++; # start from 1, 0 is used to set as 0
|
||||
@@ -3020,7 +2972,7 @@ sub lparnetbootexp
|
||||
} else {
|
||||
for( $i = 0; $i < $adapter_found; $i++) {
|
||||
if ($adap_type[$i] =~ /$match_pat/) {
|
||||
if (!($adap_type[$i] eq "hfi-ent")) {
|
||||
if ($adap_type[$i] eq "hfi-ent") {
|
||||
$mac_address = get_mac_addr($phandle_array[$i], $rconsole, $node, $verbose);
|
||||
$loc_code = get_adaptr_loc($phandle_array[$i], $rconsole, $node, $verbose);
|
||||
}
|
||||
|
||||
+177
-265
@@ -19,7 +19,6 @@ use File::Path;
|
||||
use Math::BigInt;
|
||||
use Socket;
|
||||
use xCAT::GlobalDef;
|
||||
#use Data::Dumper;
|
||||
use strict;
|
||||
use warnings "all";
|
||||
my $socket6support = eval { require Socket6 };
|
||||
@@ -643,11 +642,16 @@ sub get_nic_ip
|
||||
{
|
||||
my $nic;
|
||||
my %iphash;
|
||||
my $cmd = "ifconfig -a";
|
||||
my $result = `$cmd`;
|
||||
my $mode = "MULTICAST";
|
||||
my $payingattention=0;
|
||||
my $interface;
|
||||
my $keepcurrentiface;
|
||||
|
||||
#############################################
|
||||
# Error running command
|
||||
#############################################
|
||||
if ( !$result ) {
|
||||
return undef;
|
||||
}
|
||||
|
||||
if (xCAT::Utils->isAIX()) {
|
||||
##############################################################
|
||||
@@ -659,14 +663,6 @@ sub get_nic_ip
|
||||
# en1: ...
|
||||
#
|
||||
##############################################################
|
||||
my $cmd = "ifconfig -a";
|
||||
my $result = `$cmd`;
|
||||
#############################################
|
||||
# Error running command
|
||||
#############################################
|
||||
if ( !$result ) {
|
||||
return undef;
|
||||
}
|
||||
my @adapter = split /(\w+\d+):\s+flags=/, $result;
|
||||
foreach ( @adapter ) {
|
||||
if ($_ =~ /^(en\d)/) {
|
||||
@@ -686,39 +682,37 @@ sub get_nic_ip
|
||||
}
|
||||
}
|
||||
}
|
||||
else { # linux
|
||||
my @ipoutput = `ip addr`;
|
||||
#############################################
|
||||
# Error running command
|
||||
#############################################
|
||||
if ( !@ipoutput ) {
|
||||
return undef;
|
||||
}
|
||||
foreach my $line (@ipoutput) {
|
||||
if ($line =~ /^\d/) { # new interface, new context..
|
||||
if ($interface and not $keepcurrentiface) {
|
||||
#don't bother reporting unusable nics
|
||||
delete $iphash{$interface};
|
||||
else {
|
||||
##############################################################
|
||||
# Should look like this for Linux:
|
||||
# eth0 Link encap:Ethernet HWaddr 00:02:55:7B:06:30
|
||||
# inet addr:9.114.154.193 Bcast:9.114.154.223
|
||||
# inet6 addr: fe80::202:55ff:fe7b:630/64 Scope:Link
|
||||
# UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
|
||||
# RX packets:1280982 errors:0 dropped:0 overruns:0 frame:0
|
||||
# TX packets:3535776 errors:0 dropped:0 overruns:0 carrier:0
|
||||
# collisions:0 txqueuelen:1000
|
||||
# RX bytes:343489371 (327.5 MiB) TX bytes:870969610 (830.6 MiB)
|
||||
# Base address:0x2600 Memory:fbfe0000-fc0000080
|
||||
#
|
||||
# eth1 ...
|
||||
#
|
||||
##############################################################
|
||||
my @adapter= split /\n{2,}/, $result;
|
||||
foreach ( @adapter ) {
|
||||
if ( !($_ =~ /LOOPBACK / ) and
|
||||
$_ =~ /UP / and
|
||||
$_ =~ /$mode / ) {
|
||||
my @ip = split /\n/;
|
||||
for my $ent ( @ip ) {
|
||||
if ($ent =~ /^(eth\d|ib\d|hf\d)\s+/) {
|
||||
$nic = $1;
|
||||
}
|
||||
if ( $ent =~ /^\s*inet addr:\s*(\d+\.\d+\.\d+\.\d+)/ ) {
|
||||
$iphash{$nic} = $1;
|
||||
next;
|
||||
}
|
||||
}
|
||||
$keepcurrentiface=0;
|
||||
if ( !($line =~ /LOOPBACK/ ) and
|
||||
$line =~ /UP( |,|>)/ and
|
||||
$line =~ /$mode/ ) {
|
||||
|
||||
$payingattention=1;
|
||||
$line =~ /^([^:]*): ([^:]*):/;
|
||||
$interface=$2;
|
||||
} else {
|
||||
$payingattention=0;
|
||||
next;
|
||||
}
|
||||
}
|
||||
unless ($payingattention) { next; }
|
||||
if ($line =~ /inet/) {
|
||||
$keepcurrentiface=1;
|
||||
}
|
||||
if ( $line =~ /^\s*inet \s*(\d+\.\d+\.\d+\.\d+)/ ) {
|
||||
$iphash{$interface} = $1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1601,124 +1595,56 @@ sub thishostisnot
|
||||
=cut
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
#sub gethost_ips1
|
||||
#{
|
||||
# my ($class) = @_;
|
||||
# my $cmd;
|
||||
# my @ipaddress;
|
||||
# $cmd = "ifconfig" . " -a";
|
||||
# $cmd = $cmd . "| grep \"inet\"";
|
||||
# my @result = xCAT::Utils->runcmd($cmd, 0);
|
||||
# if ($::RUNCMD_RC != 0)
|
||||
# {
|
||||
# xCAT::MsgUtils->message("S", "Error from $cmd\n");
|
||||
# exit $::RUNCMD_RC;
|
||||
# }
|
||||
# foreach my $addr (@result)
|
||||
# {
|
||||
# my @ip;
|
||||
# if (xCAT::Utils->isLinux())
|
||||
# {
|
||||
# if ($addr =~ /inet6/)
|
||||
# {
|
||||
# #TODO, Linux ipv6
|
||||
# }
|
||||
# else
|
||||
# {
|
||||
# my ($inet, $addr1, $Bcast, $Mask) = split(" ", $addr);
|
||||
# #@ip = split(":", $addr1);
|
||||
# #push @ipaddress, $ip[1];
|
||||
# $addr1 =~ s/.*://;
|
||||
# push @ipaddress, $addr1;
|
||||
# }
|
||||
# }
|
||||
# else
|
||||
# { #AIX
|
||||
# if ($addr =~ /inet6/)
|
||||
# {
|
||||
# $addr =~ /\s*inet6\s+([\da-fA-F:]+).*\/(\d+)/;
|
||||
# my $v6ip = $1;
|
||||
# my $v6mask = $2;
|
||||
# if ($v6ip)
|
||||
# {
|
||||
# push @ipaddress, $v6ip;
|
||||
# }
|
||||
# }
|
||||
# else
|
||||
# {
|
||||
# my ($inet, $addr1, $netmask, $mask1, $Bcast, $bcastaddr) =
|
||||
# split(" ", $addr);
|
||||
# push @ipaddress, $addr1;
|
||||
# }
|
||||
#
|
||||
# }
|
||||
# }
|
||||
# my @names = @ipaddress;
|
||||
# foreach my $ipaddr (@names)
|
||||
# {
|
||||
# my $hostname = xCAT::NetworkUtils->gethostname($ipaddr);
|
||||
# if ($hostname)
|
||||
# {
|
||||
# my @shorthost = split(/\./, $hostname);
|
||||
# push @ipaddress, $shorthost[0];
|
||||
# }
|
||||
# }
|
||||
#
|
||||
# return @ipaddress;
|
||||
#}
|
||||
|
||||
|
||||
sub gethost_ips
|
||||
{
|
||||
my ($class) = @_;
|
||||
my $cmd;
|
||||
my @ipaddress;
|
||||
if (xCAT::Utils->isLinux())
|
||||
$cmd = "ifconfig" . " -a";
|
||||
$cmd = $cmd . "| grep \"inet\"";
|
||||
my @result = xCAT::Utils->runcmd($cmd, 0);
|
||||
if ($::RUNCMD_RC != 0)
|
||||
{
|
||||
$cmd="ip -4 --oneline addr show |awk -F ' ' '{print \$4}'|awk -F '/' '{print \$1}'";
|
||||
my @result =xCAT::Utils->runcmd($cmd);
|
||||
if ($::RUNCMD_RC != 0)
|
||||
{
|
||||
xCAT::MsgUtils->message("S", "Error from $cmd\n");
|
||||
exit $::RUNCMD_RC;
|
||||
}
|
||||
|
||||
push @ipaddress, @result;
|
||||
xCAT::MsgUtils->message("S", "Error from $cmd\n");
|
||||
exit $::RUNCMD_RC;
|
||||
}
|
||||
else
|
||||
{ #AIX
|
||||
|
||||
$cmd = "ifconfig" . " -a";
|
||||
$cmd = $cmd . "| grep \"inet\"";
|
||||
my @result = xCAT::Utils->runcmd($cmd, 0);
|
||||
if ($::RUNCMD_RC != 0)
|
||||
{
|
||||
xCAT::MsgUtils->message("S", "Error from $cmd\n");
|
||||
exit $::RUNCMD_RC;
|
||||
}
|
||||
|
||||
foreach my $addr (@result)
|
||||
{
|
||||
if ($addr =~ /inet6/)
|
||||
{
|
||||
$addr =~ /\s*inet6\s+([\da-fA-F:]+).*\/(\d+)/;
|
||||
my $v6ip = $1;
|
||||
my $v6mask = $2;
|
||||
if ($v6ip)
|
||||
{
|
||||
push @ipaddress, $v6ip;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
my ($inet, $addr1, $netmask, $mask1, $Bcast, $bcastaddr) =
|
||||
split(" ", $addr);
|
||||
push @ipaddress, $addr1;
|
||||
}
|
||||
foreach my $addr (@result)
|
||||
{
|
||||
my @ip;
|
||||
if (xCAT::Utils->isLinux())
|
||||
{
|
||||
if ($addr =~ /inet6/)
|
||||
{
|
||||
#TODO, Linux ipv6
|
||||
}
|
||||
else
|
||||
{
|
||||
my ($inet, $addr1, $Bcast, $Mask) = split(" ", $addr);
|
||||
@ip = split(":", $addr1);
|
||||
push @ipaddress, $ip[1];
|
||||
}
|
||||
}
|
||||
else
|
||||
{ #AIX
|
||||
if ($addr =~ /inet6/)
|
||||
{
|
||||
$addr =~ /\s*inet6\s+([\da-fA-F:]+).*\/(\d+)/;
|
||||
my $v6ip = $1;
|
||||
my $v6mask = $2;
|
||||
if ($v6ip)
|
||||
{
|
||||
push @ipaddress, $v6ip;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
my ($inet, $addr1, $netmask, $mask1, $Bcast, $bcastaddr) =
|
||||
split(" ", $addr);
|
||||
push @ipaddress, $addr1;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
my @names = @ipaddress;
|
||||
foreach my $ipaddr (@names)
|
||||
{
|
||||
@@ -1729,9 +1655,9 @@ sub gethost_ips
|
||||
push @ipaddress, $shorthost[0];
|
||||
}
|
||||
}
|
||||
|
||||
return @ipaddress;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
=head3 get_subnet_aix
|
||||
@@ -1907,6 +1833,102 @@ sub validate_ip
|
||||
}
|
||||
return([0]);
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
=head3 getFacingIP
|
||||
Gets the ip address of the adapter of the localhost that is facing the
|
||||
the given node.
|
||||
Assume it is the same as my_ip_facing...
|
||||
Arguments:
|
||||
The name of the node that is facing the localhost.
|
||||
Returns:
|
||||
The ip address of the adapter that faces the node.
|
||||
|
||||
=cut
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
sub getFacingIP
|
||||
{
|
||||
my ($class, $node) = @_;
|
||||
my $ip;
|
||||
my $cmd;
|
||||
my @ipaddress;
|
||||
|
||||
my $nodeip = inet_ntoa(inet_aton($node));
|
||||
unless ($nodeip =~ /\d+\.\d+\.\d+\.\d+/)
|
||||
{
|
||||
return 0; #Not supporting IPv6 here IPV6TODO
|
||||
}
|
||||
|
||||
$cmd = "ifconfig" . " -a";
|
||||
$cmd = $cmd . "| grep \"inet \"";
|
||||
my @result = xCAT::Utils->runcmd($cmd, 0);
|
||||
if ($::RUNCMD_RC != 0)
|
||||
{
|
||||
xCAT::MsgUtils->message("S", "Error from $cmd\n");
|
||||
exit $::RUNCMD_RC;
|
||||
}
|
||||
|
||||
# split node address
|
||||
my ($n1, $n2, $n3, $n4) = split('\.', $nodeip);
|
||||
|
||||
foreach my $addr (@result)
|
||||
{
|
||||
my $ip;
|
||||
my $mask;
|
||||
if (xCAT::Utils->isLinux())
|
||||
{
|
||||
my ($inet, $addr1, $Bcast, $Mask) = split(" ", $addr);
|
||||
if ((!$addr1) || (!$Mask)) { next; }
|
||||
my @ips = split(":", $addr1);
|
||||
my @masks = split(":", $Mask);
|
||||
$ip = $ips[1];
|
||||
$mask = $masks[1];
|
||||
}
|
||||
else
|
||||
{ #AIX
|
||||
my ($inet, $addr1, $netmask, $mask1, $Bcast, $bcastaddr) =
|
||||
split(" ", $addr);
|
||||
if ((!$addr1) && (!$mask1)) { next; }
|
||||
$ip = $addr1;
|
||||
$mask1 =~ s/0x//;
|
||||
$mask =
|
||||
`printf "%d.%d.%d.%d" \$(echo "$mask1" | sed 's/../0x& /g')`;
|
||||
}
|
||||
|
||||
if ($ip && $mask)
|
||||
{
|
||||
|
||||
# split interface IP
|
||||
my ($h1, $h2, $h3, $h4) = split('\.', $ip);
|
||||
|
||||
# split mask
|
||||
my ($m1, $m2, $m3, $m4) = split('\.', $mask);
|
||||
|
||||
# AND this interface IP with the netmask of the network
|
||||
my $a1 = ((int $h1) & (int $m1));
|
||||
my $a2 = ((int $h2) & (int $m2));
|
||||
my $a3 = ((int $h3) & (int $m3));
|
||||
my $a4 = ((int $h4) & (int $m4));
|
||||
|
||||
# AND node IP with the netmask of the network
|
||||
my $b1 = ((int $n1) & (int $m1));
|
||||
my $b2 = ((int $n2) & (int $m2));
|
||||
my $b3 = ((int $n3) & (int $m3));
|
||||
my $b4 = ((int $n4) & (int $m4));
|
||||
|
||||
if (($b1 == $a1) && ($b2 == $a2) && ($b3 == $a3) && ($b4 == $a4))
|
||||
{
|
||||
return $ip;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
xCAT::MsgUtils->message("S", "Cannot find master for the node $node\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
=head3 isIpaddr
|
||||
@@ -1959,108 +1981,6 @@ sub isIpaddr
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
=head3 getNodeNameservers
|
||||
Description:
|
||||
Get nameservers of specified nodes.
|
||||
The priority: noderes.nameservers > networks.nameservers > site.nameservers
|
||||
Arguments:
|
||||
node: node name list
|
||||
Returns:
|
||||
Return a hash ref, of the $nameservers{$node}
|
||||
undef - Failed to get the nameservers
|
||||
Globals:
|
||||
none
|
||||
Error:
|
||||
none
|
||||
Example:
|
||||
my $nameservers = xCAT::NetworkUtils::getNodeNameservers(\@node);
|
||||
Comments:
|
||||
none
|
||||
|
||||
=cut
|
||||
#-------------------------------------------------------------------------------
|
||||
sub getNodeNameservers{
|
||||
my $nodes=shift;
|
||||
if( $nodes =~ /xCAT::NetworkUtils/)
|
||||
{
|
||||
$nodes=shift;
|
||||
}
|
||||
my @nodelist = @$nodes;
|
||||
my %nodenameservers;
|
||||
my $nrtab = xCAT::Table->new('noderes',-create=>0);
|
||||
my %nrhash = %{$nrtab->getNodesAttribs(\@nodelist,['nameservers'])};
|
||||
|
||||
my $nettab = xCAT::Table->new("networks");
|
||||
my %nethash = xCAT::DBobjUtils->getNetwkInfo( \@nodelist );
|
||||
|
||||
my @nameservers = xCAT::TableUtils->get_site_attribute("nameservers");
|
||||
my $sitenameservers=$nameservers[0];
|
||||
|
||||
|
||||
foreach my $node (@nodelist){
|
||||
if ($nrhash{$node} and $nrhash{$node}->[0] and $nrhash{$node}->[0]->{nameservers})
|
||||
{
|
||||
$nodenameservers{$node}=$nrhash{$node}->[0]->{nameservers};
|
||||
}elsif($nethash{$node}{nameservers})
|
||||
{
|
||||
$nodenameservers{$node}=$nethash{$node}{nameservers};
|
||||
}elsif($sitenameservers)
|
||||
{
|
||||
$nodenameservers{$node}=$sitenameservers;
|
||||
}
|
||||
}
|
||||
|
||||
return \%nodenameservers;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
=head3 getNodeGateway
|
||||
Description:
|
||||
Get gateway from the networks table of the node.
|
||||
|
||||
Arguments:
|
||||
ip: the ip address of the node
|
||||
Returns:
|
||||
Return a string, of the gateway
|
||||
undef - Failed to get the gateway
|
||||
Globals:
|
||||
none
|
||||
Error:
|
||||
none
|
||||
Example:
|
||||
my $gateway = xCAT::NetworkUtils::getNodeGateway('192.168.1.0');
|
||||
Comments:
|
||||
none
|
||||
|
||||
=cut
|
||||
#-------------------------------------------------------------------------------
|
||||
sub getNodeGateway
|
||||
{
|
||||
my $ip=shift;
|
||||
if( $ip =~ /xCAT::NetworkUtils/)
|
||||
{
|
||||
$ip=shift;
|
||||
}
|
||||
my $gateway=undef;
|
||||
|
||||
my $nettab = xCAT::Table->new("networks");
|
||||
if ($nettab) {
|
||||
my @nets = $nettab->getAllAttribs('net','mask','gateway');
|
||||
foreach my $net (@nets) {
|
||||
if (xCAT::NetworkUtils::isInSameSubnet( $net->{'net'}, $ip, $net->{'mask'}, 0)) {
|
||||
$gateway=$net->{'gateway'};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return $gateway;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
=head3 getNodeNetworkCfg
|
||||
@@ -2087,27 +2007,19 @@ sub getNodeGateway
|
||||
sub getNodeNetworkCfg
|
||||
{
|
||||
my $node = shift;
|
||||
if( $node =~ /xCAT::NetworkUtils/)
|
||||
{
|
||||
$node =shift;
|
||||
}
|
||||
|
||||
my $nets = xCAT::NetworkUtils::my_nets();
|
||||
my $ip = xCAT::NetworkUtils->getipaddr($node);
|
||||
my $mask = undef;
|
||||
my $gateway = undef;
|
||||
for my $net (keys %$nets)
|
||||
{
|
||||
my $netname;
|
||||
($netname,$mask) = split /\//, $net;
|
||||
last if ( xCAT::NetworkUtils::isInSameSubnet( $netname, $ip, $mask, 1));
|
||||
}
|
||||
$gateway=xCAT::NetworkUtils::getNodeGateway($ip);
|
||||
return ($ip, $node, $gateway, xCAT::NetworkUtils::formatNetmask($mask,1,0));
|
||||
return ($ip, $node, undef, xCAT::NetworkUtils::formatNetmask($mask,1,0));
|
||||
}
|
||||
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
=head3 get_hdwr_ip
|
||||
|
||||
@@ -149,7 +149,7 @@ sub nodesbycriteria {
|
||||
}
|
||||
if ($neednewcache) {
|
||||
if ($nodelist) {
|
||||
#$nodelist->_clear_cache();
|
||||
$nodelist->_clear_cache();
|
||||
$nodelist->_build_cache(\@cachedcolumns);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ sub parse_args {
|
||||
my %opt = ();
|
||||
my $cmd = $request->{command};
|
||||
my $args = $request->{arg};
|
||||
my @VERSION = qw( 2.1 );
|
||||
|
||||
#############################################
|
||||
# Responds with usage statement
|
||||
@@ -59,8 +60,7 @@ sub parse_args {
|
||||
# Option -v for version
|
||||
####################################
|
||||
if ( exists( $opt{v} )) {
|
||||
my $version = xCAT::Utils->Version();
|
||||
return ([$version]);
|
||||
return( \@VERSION );
|
||||
}
|
||||
|
||||
if ( exists( $opt{s} ) ){
|
||||
@@ -350,27 +350,6 @@ sub do_rnetboot {
|
||||
last;
|
||||
}
|
||||
}
|
||||
|
||||
# Set the boot mode to norm from 'of' (open firmware)
|
||||
# NOW, only necessary for IVM
|
||||
my $hwtype = @$exp[2];
|
||||
if ($hwtype eq "ivm") {
|
||||
my $server = @$exp[3];
|
||||
|
||||
# creat connection first
|
||||
my @newexp = xCAT::PPCcli::connect( $request, $hwtype, $server );
|
||||
if (ref($newexp[0]) eq "Expect" ) {
|
||||
my $cfg = "lpar_id=@$d[0],boot_mode=norm";
|
||||
# change the boot mode to 'norm'
|
||||
xCAT::PPCcli::chsyscfg(\@newexp, "prof", $d, $cfg);
|
||||
xCAT::PPCcli::disconnect(\@newexp);
|
||||
} else {
|
||||
my $rsp;
|
||||
$rsp->{data} = ["Failed to set the boot mode to normal. For rnetboot command, you have to rpower off and then on the node after finishing the OS deployment."];
|
||||
xCAT::MsgUtils->message("E", $rsp, $request->{callback});
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
@@ -436,9 +436,9 @@ sub sshcfg {
|
||||
#####################################
|
||||
# userid@host not found in key file
|
||||
#####################################
|
||||
#if ( $sshkey !~ /\s+(\S+\@\S+$)/ ) {
|
||||
# return( [[$server,"Cannot find userid\@host in '$fname'",RC_ERROR]] );
|
||||
#}
|
||||
if ( $sshkey !~ /\s+(\S+\@\S+$)/ ) {
|
||||
return( [[$server,"Cannot find userid\@host in '$fname'",RC_ERROR]] );
|
||||
}
|
||||
my $logon = $1;
|
||||
|
||||
#####################################
|
||||
|
||||
@@ -156,7 +156,7 @@ sub connect {
|
||||
# Shell prompt regexp based on HW Type
|
||||
##################################################
|
||||
my %prompt = (
|
||||
hmc => "~>\\s*\$",
|
||||
hmc => "~> \$",
|
||||
ivm => "\\\$ \$"
|
||||
);
|
||||
##################################################
|
||||
|
||||
+19
-14
@@ -296,37 +296,42 @@ sub renergy {
|
||||
$deadnodes{$_}=1;
|
||||
}
|
||||
open (NMAP, "nmap -PE --system-dns --send-ip -sP ". join(' ',@hcps_ip) . " 2> /dev/null|") or die("Cannot open nmap pipe: $!");
|
||||
my $node;
|
||||
my $node1;
|
||||
my $msg1;
|
||||
while (<NMAP>) {
|
||||
#print "$_\n";
|
||||
if (/Host (.*) \((.*)\) appears to be up/) {
|
||||
$node=$2;
|
||||
unless ($deadnodes{$node}) {
|
||||
$node1=$2;
|
||||
unless ($deadnodes{$node1}) {
|
||||
foreach (keys %deadnodes) {
|
||||
if ($node =~ /^$_\./) {
|
||||
$node = $_;
|
||||
if ($node1 =~ /^$_\./) {
|
||||
$node1 = $_;
|
||||
last;
|
||||
}
|
||||
}
|
||||
}
|
||||
delete $deadnodes{$node};
|
||||
delete $deadnodes{$node1};
|
||||
if ($verbose) {
|
||||
push @return_msg, [$node, $_, 0];
|
||||
}
|
||||
push(@pingable_hcp, $node);
|
||||
} elsif (/Nmap scan report for ([^ ]*)/) {
|
||||
$node=$1;
|
||||
push(@pingable_hcp, $node1);
|
||||
} elsif (/Nmap scan report for ([^ ]*) \((.*)\)/) {
|
||||
$node1=$2;
|
||||
$msg1=$_;
|
||||
} elsif (/Host is up./) {
|
||||
unless ($deadnodes{$node}) {
|
||||
unless ($deadnodes{$node1}) {
|
||||
foreach (keys %deadnodes) {
|
||||
if ($node =~ /^$_\./) {
|
||||
$node = $_;
|
||||
if ($node1 =~ /^$_\./) {
|
||||
$node1 = $_;
|
||||
last;
|
||||
}
|
||||
}
|
||||
}
|
||||
delete $deadnodes{$node};
|
||||
push(@pingable_hcp, $node);
|
||||
delete $deadnodes{$node1};
|
||||
if ($verbose) {
|
||||
push @return_msg, [$node, "$msg1$_", 0];
|
||||
}
|
||||
push(@pingable_hcp, $node1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -144,16 +144,12 @@ sub connect {
|
||||
##################################
|
||||
# Set options
|
||||
##################################
|
||||
#my $hosttab = xCAT::Table->new( 'hosts' );
|
||||
#if ( $hosttab) {
|
||||
# my $hostshash = $hosttab->getNodeAttribs( $server, [qw(ip otherinterfaces)]);
|
||||
# if ( $hostshash ) {
|
||||
# $server = $hostshash->{ip};
|
||||
# }
|
||||
#}
|
||||
$server = xCAT::NetworkUtils::getNodeIPaddress( $server );
|
||||
unless ($server) {
|
||||
return( "Unable to get IP address for $server" );
|
||||
my $hosttab = xCAT::Table->new( 'hosts' );
|
||||
if ( $hosttab) {
|
||||
my $hostshash = $hosttab->getNodeAttribs( $server, [qw(ip otherinterfaces)]);
|
||||
if ( $hostshash ) {
|
||||
$server = $hostshash->{ip};
|
||||
}
|
||||
}
|
||||
# my $serverip = inet_ntoa(inet_aton($server));
|
||||
my $url = "https://$server/cgi-bin/cgi?form=2";
|
||||
|
||||
@@ -347,7 +347,7 @@ sub bus {
|
||||
#################################
|
||||
# Output header
|
||||
#################################
|
||||
push @result, [$name,"I/O Bus Information", 0];
|
||||
push @result, [$name,"I/O Bus Information"];
|
||||
|
||||
#################################
|
||||
# Output error
|
||||
@@ -532,7 +532,7 @@ sub config {
|
||||
#################################
|
||||
# Output header
|
||||
#################################
|
||||
push @result, [$name,"Machine Configuration Info", 0];
|
||||
push @result, [$name,"Machine Configuration Info"];
|
||||
my $i;
|
||||
|
||||
foreach ( @prefix ) {
|
||||
|
||||
@@ -203,7 +203,7 @@ sub voltage {
|
||||
# Voltages available in frame
|
||||
#################################
|
||||
if ( @$d[4] ne "bpa" ) {
|
||||
push @result, [$name,"$text Only available for BPA",0];
|
||||
push @result, [$name,"$text Only available for BPA",1];
|
||||
next;
|
||||
}
|
||||
my $volt = enumerate_volt( $exp, $d );
|
||||
@@ -256,7 +256,7 @@ sub temp {
|
||||
# No frame commands for IVM
|
||||
#################################
|
||||
if ( $hwtype eq "ivm" ) {
|
||||
push @result, [$name,"$prefix Not available (No BPA)",0];
|
||||
push @result, [$name,"$prefix Not available (No BPA)",1];
|
||||
next;
|
||||
}
|
||||
#################################
|
||||
@@ -264,14 +264,14 @@ sub temp {
|
||||
#################################
|
||||
if ( @$d[4] !~ /^(fsp|cec|lpar)$/ ) {
|
||||
my $text = "$prefix Only available for CEC/LPAR";
|
||||
push @result, [$name,$text,0];
|
||||
push @result, [$name,$text,1];
|
||||
next;
|
||||
}
|
||||
#################################
|
||||
# Error - No frame
|
||||
#################################
|
||||
if ( $mtms eq "0" ) {
|
||||
push @result, [$name,"$prefix Not available (No BPA)",0];
|
||||
push @result, [$name,"$prefix Not available (No BPA)",1];
|
||||
next;
|
||||
}
|
||||
#################################
|
||||
|
||||
@@ -265,7 +265,6 @@ sub rackformat_to_numricformat{
|
||||
values are attributes of a specific nic, like:
|
||||
type : nic type
|
||||
hostnamesuffix: hostname suffix
|
||||
hostnameprefix: hostname prefix
|
||||
customscript: custom script for this nic
|
||||
network: network name for this nic
|
||||
ip: ip address of this nic.
|
||||
@@ -277,7 +276,7 @@ sub get_nodes_nic_attrs{
|
||||
my $nodes = shift;
|
||||
|
||||
my $nicstab = xCAT::Table->new( 'nics');
|
||||
my $entry = $nicstab->getNodesAttribs($nodes, ['nictypes', 'nichostnamesuffixes', 'nichostnameprefixes', 'niccustomscripts', 'nicnetworks', 'nicips']);
|
||||
my $entry = $nicstab->getNodesAttribs($nodes, ['nictypes', 'nichostnamesuffixes', 'niccustomscripts', 'nicnetworks', 'nicips']);
|
||||
|
||||
my %nicsattrs;
|
||||
my @nicattrslist;
|
||||
@@ -309,20 +308,6 @@ sub get_nodes_nic_attrs{
|
||||
}
|
||||
}
|
||||
|
||||
if($entry->{$node}->[0]->{'nichostnameprefixes'}){
|
||||
|
||||
@nicattrslist = split(",", $entry->{$node}->[0]->{'nichostnameprefixes'});
|
||||
foreach (@nicattrslist){
|
||||
my @nicattrs;
|
||||
if ($_ =~ /!/) {
|
||||
@nicattrs = split("!", $_);
|
||||
} else {
|
||||
@nicattrs = split(":", $_);
|
||||
}
|
||||
$nicsattrs{$node}{$nicattrs[0]}{'hostnameprefix'} = $nicattrs[1];
|
||||
}
|
||||
}
|
||||
|
||||
if($entry->{$node}->[0]->{'niccustomscripts'}){
|
||||
@nicattrslist = split(",", $entry->{$node}->[0]->{'niccustomscripts'});
|
||||
foreach (@nicattrslist){
|
||||
@@ -748,27 +733,6 @@ sub get_imageprofile_prov_method
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
=head3 get_imageprofile_prov_osvers
|
||||
Description : Get A node's provisioning os version and profile from its imageprofile attribute.
|
||||
Arguments : $imgprofilename - imageprofile name
|
||||
Returns : node's osversion and profile
|
||||
=cut
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
sub get_imageprofile_prov_osvers
|
||||
{
|
||||
|
||||
my $class = shift;
|
||||
my $imgprofilename = shift;
|
||||
my $osimgtab = xCAT::Table->new('osimage');
|
||||
my $osimgentry = ($osimgtab->getAllAttribsWhere("imagename = '$imgprofilename'", 'ALL' ))[0];
|
||||
my $osversion = $osimgentry->{'osvers'};
|
||||
my $profile = $osimgentry->{'profile'};
|
||||
return ($osversion, $profile);
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
=head3 check_profile_consistent
|
||||
Description : Check if three profile consistent
|
||||
Arguments : $imageprofile - image profile name
|
||||
@@ -860,11 +824,6 @@ sub check_profile_consistent{
|
||||
return 0, "$nictype networkprofile must use with hardwareprofile.";
|
||||
}
|
||||
}
|
||||
|
||||
if ($mgt eq 'vm')
|
||||
{
|
||||
return 1, "";
|
||||
}
|
||||
|
||||
# For nodetype is lpar node, not need to check the nictype as it is not required for lpar node
|
||||
if (not $nictype and $mgt and $nodetype ne 'lpar' ) {
|
||||
@@ -1041,40 +1000,6 @@ sub parse_nodeinfo_file
|
||||
return 1, "";
|
||||
}
|
||||
|
||||
#-------------------------------------------------------
|
||||
|
||||
=head3 update the table prodkey, in order to support windows
|
||||
per node license key
|
||||
|
||||
Returns: $retcode.
|
||||
$retcode = 1. update failed, the value is undef
|
||||
$retcode = 0. save into db is OK..
|
||||
=cut
|
||||
#-------------------------------------------------------
|
||||
|
||||
sub update_windows_prodkey
|
||||
{
|
||||
my $class = shift;
|
||||
my $node = shift;
|
||||
my $product = shift;
|
||||
my $key = shift;
|
||||
unless(defined($node) && defined($product) && defined($key))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
# please notice this db usage
|
||||
my %keyhash;
|
||||
my %updates;
|
||||
$keyhash{'node'} = $node;
|
||||
$updates{'product'} = $product;
|
||||
$updates{'key'} = $key;
|
||||
my $tab = xCAT::Table->new('prodkey', -create=>1, -autocommit=>0);
|
||||
$tab->setAttribs( \%keyhash,\%updates );
|
||||
$tab->commit;
|
||||
$tab->close;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
=head3 check_nicips
|
||||
Description: Check if the nicips defined in MAC file is correct
|
||||
|
||||
@@ -35,7 +35,7 @@ package xCAT::RemoteShellExp;
|
||||
node.
|
||||
DSH_TO_USERID - The userid on the node where the ssh keys will be updated.
|
||||
DSH_ENABLE_SSH - Node to node root passwordless ssh will be setup.
|
||||
DSH_ZONE_SSHKEYS - directory containing the zones root .ssh keys
|
||||
|
||||
|
||||
Usage: remoteshellexp
|
||||
[-t node list] test ssh connection to the node
|
||||
@@ -144,7 +144,7 @@ sub remoteshellexp
|
||||
} else {
|
||||
$from_userid="root";
|
||||
}
|
||||
# set User on the node where we will send the keys
|
||||
# set User on the node where we will send the keys
|
||||
# this id can be a local id as well as root
|
||||
if ($ENV{'DSH_TO_USERID'}) {
|
||||
$to_userid=$ENV{'DSH_TO_USERID'};
|
||||
@@ -154,19 +154,18 @@ sub remoteshellexp
|
||||
# set User home directory to find the ssh public key to send
|
||||
# For non-root ids information may not be in /etc/passwd
|
||||
# but elsewhere like LDAP
|
||||
|
||||
if ($ENV{'DSH_FROM_USERID_HOME'}) {
|
||||
$home=$ENV{'DSH_FROM_USERID_HOME'};
|
||||
$home=$ENV{'DSH_FROM_USERID_HOME'};
|
||||
} else {
|
||||
$home=xCAT::Utils->getHomeDir($from_userid);
|
||||
$home=xCAT::Utils->getHomeDir($from_userid);
|
||||
}
|
||||
|
||||
# This indicates we will generate new ssh keys for the user,
|
||||
# if they are not already there
|
||||
# unless using zones
|
||||
my $key="$home/.ssh/id_rsa";
|
||||
my $key2="$home/.ssh/id_rsa.pub";
|
||||
# Check to see if empty
|
||||
if (-z $key) {
|
||||
my $key="$home/.ssh/id_rsa";
|
||||
my $key2="$home/.ssh/id_rsa.pub";
|
||||
# Check to see if empty
|
||||
if (-z $key) {
|
||||
my $rsp = {};
|
||||
$rsp->{error}->[0] =
|
||||
"The $key file is empty. Remove it and rerun the command.";
|
||||
@@ -184,7 +183,8 @@ sub remoteshellexp
|
||||
}
|
||||
if (($flag eq "k") && (!(-e $key)))
|
||||
{
|
||||
# updating keys and the key file does not exist
|
||||
# if the file size of the id_rsa key is 0, tell them to remove it
|
||||
# and run the command again
|
||||
$rc=xCAT::RemoteShellExp->gensshkeys($expecttimeout);
|
||||
}
|
||||
# send ssh keys to the nodes/devices, to setup passwordless ssh
|
||||
@@ -200,9 +200,6 @@ sub remoteshellexp
|
||||
if ($ssh_setup_cmd) { # setup ssh on devices
|
||||
$rc=xCAT::RemoteShellExp->senddeviceskeys($remoteshell,$remotecopy,$to_userid,$to_user_password,$home,$ssh_setup_cmd,$nodes, $expecttimeout);
|
||||
} else { #setup ssh on nodes
|
||||
if ($ENV{'DSH_ZONE_SSHKEYS'}) { # if using zones the override the location of the keys
|
||||
$home= $ENV{'DSH_ZONE_SSHKEYS'};
|
||||
}
|
||||
$rc=xCAT::RemoteShellExp->sendnodeskeys($remoteshell,$remotecopy,$to_userid,$to_user_password,$home,$nodes, $expecttimeout);
|
||||
}
|
||||
}
|
||||
@@ -498,15 +495,11 @@ sub sendnodeskeys
|
||||
# in $HOME/.ssh/tmp/authorized_keys
|
||||
# copy to the node to the temp directory
|
||||
# scp $HOME/.ssh/tmp/authorized_keys to_userid@<node>:/tmp/$to_userid/.ssh
|
||||
# scp $HOME/.ssh/id_rsa.pub to_userid@<node>:/tmp/$to_userid/.ssh
|
||||
# Note if using zones, the keys do not come from ~/.ssh but from the
|
||||
# zone table, sshkeydir attribute. For zones the userid is always root
|
||||
# If you are going to enable ssh to ssh between nodes, then
|
||||
# scp $HOME/.ssh/id_rsa to that temp directory on the node
|
||||
# copy the script $HOME/.ssh/copy.sh to the node, it will do the
|
||||
# the work of setting up the user's ssh keys and clean up
|
||||
# ssh (run) copy.sh on the node
|
||||
|
||||
my @nodelist=split(/,/,$nodes);
|
||||
foreach my $node (@nodelist) {
|
||||
$sendkeys = new Expect;
|
||||
@@ -614,11 +607,11 @@ sub sendnodeskeys
|
||||
my $spawncopyfiles;
|
||||
if ($ENV{'DSH_ENABLE_SSH'}) { # we will enable node to node ssh
|
||||
$spawncopyfiles=
|
||||
"$remotecopy $home/.ssh/id_rsa $home/.ssh/id_rsa.pub $home/.ssh/copy.sh $home/.ssh/tmp/authorized_keys $to_userid\@$node:/tmp/$to_userid/.ssh ";
|
||||
"$remotecopy $home/.ssh/id_rsa $home/.ssh/copy.sh $home/.ssh/tmp/authorized_keys $to_userid\@$node:/tmp/$to_userid/.ssh ";
|
||||
|
||||
} else { # no node to node ssh ( don't send private key)
|
||||
$spawncopyfiles=
|
||||
"$remotecopy $home/.ssh/id_rsa.pub $home/.ssh/copy.sh $home/.ssh/tmp/authorized_keys $to_userid\@$node:/tmp/$to_userid/.ssh ";
|
||||
"$remotecopy $home/.ssh/copy.sh $home/.ssh/tmp/authorized_keys $to_userid\@$node:/tmp/$to_userid/.ssh ";
|
||||
}
|
||||
# send copy command
|
||||
unless ($sendkeys->spawn($spawncopyfiles))
|
||||
@@ -810,10 +803,6 @@ sub senddeviceskeys
|
||||
# add to the command
|
||||
$setupcmd .=$key;
|
||||
$setupcmd .="\"";
|
||||
# Special case for vios
|
||||
if ($ENV{DEVICETYPE} eq 'vios') {
|
||||
$setupcmd = "\"echo $key | tee -a ~/.ssh/authorized_keys2\"";
|
||||
}
|
||||
# For each input device
|
||||
my @nodelist=split(/,/,$nodes);
|
||||
foreach my $node (@nodelist) {
|
||||
|
||||
Executable → Regular
+428
-590
File diff suppressed because it is too large
Load Diff
Executable → Regular
+130
-378
@@ -134,7 +134,7 @@ litetree => {
|
||||
table_desc => 'Directory hierarchy to traverse to get the initial contents of node files. The files that are specified in the litefile table are searched for in the directories specified in this table.',
|
||||
descriptions => {
|
||||
priority => 'This number controls what order the directories are searched. Directories are searched from smallest priority number to largest.',
|
||||
image => "The name of the image (as specified in the osimage table) that will use this directory. You can also specify an image group name that is listed in the osimage.groups attribute of some osimages. 'ALL' means use this row for all images.",
|
||||
image => "The name of the image that will use this directory, as specified in the osimage table. If image is not supplied, the default is 'ALL'. 'ALL' means use it for all images.",
|
||||
directory => 'The location (hostname:path) of a directory that contains files specified in the litefile table. Variables are allowed. E.g: $noderes.nfsserver://xcatmasternode/install/$node/#CMD=uname-r#/',
|
||||
mntopts => "A comma-separated list of options to use when mounting the litetree directory. (Ex. 'soft') The default is to do a 'hard' mount.",
|
||||
comments => 'Any user-written notes.',
|
||||
@@ -148,7 +148,7 @@ litefile => {
|
||||
required => [qw(image file)], # default type is rw nfsroot
|
||||
table_desc => 'The litefile table specifies the directories and files on the statelite nodes that should be readwrite, persistent, or readonly overlay. All other files in the statelite nodes come from the readonly statelite image.',
|
||||
descriptions => {
|
||||
image => "The name of the image (as specified in the osimage table) that will use these options on this dir/file. You can also specify an image group name that is listed in the osimage.groups attribute of some osimages. 'ALL' means use this row for all images.",
|
||||
image => "The name of the image that will use these files, as specified in the osimage table. 'ALL' means use it for all images.",
|
||||
file => "The full pathname of the file. e.g: /etc/hosts. If the path is a directory, then it should be terminated with a '/'. ",
|
||||
options => "Options for the file:\n\n".
|
||||
qq{ tmpfs - It is the default option if you leave the options column blank. It provides a file or directory for the node to use when booting, its permission will be the same as the original version on the server. In most cases, it is read-write; however, on the next statelite boot, the original version of the file or directory on the server will be used, it means it is non-persistent. This option can be performed on files and directories..\n\n}.
|
||||
@@ -200,7 +200,7 @@ vm => {
|
||||
'mgr' => 'The function manager for the virtual machine',
|
||||
'host' => 'The system that currently hosts the VM',
|
||||
'migrationdest' => 'A noderange representing candidate destinations for migration (i.e. similar systems, same SAN, or other criteria that xCAT can use',
|
||||
'storage' => 'A list of storage files or devices to be used. i.e. dir:///cluster/vm/<nodename> or nfs://<server>/path/to/folder/',
|
||||
'storage' => 'A list of storage files or devices to be used. i.e. /cluster/vm/<nodename> or nfs://<server>/path/to/folder/',
|
||||
'storagemodel' => 'Model of storage devices to provide to guest',
|
||||
'cfgstore' => 'Optional location for persistant storage separate of emulated hard drives for virtualization solutions that require persistant store to place configuration data',
|
||||
'memory' => 'Megabytes of memory the VM currently should be set to.',
|
||||
@@ -267,14 +267,11 @@ virtsd => {
|
||||
},
|
||||
|
||||
storage => {
|
||||
cols => [qw(node osvolume size state storagepool hypervisor fcprange volumetag type controller comments disable)],
|
||||
cols => [qw(node osvolume size state storagepool hypervisor fcprange volumetag comments disable)],
|
||||
keys => [qw(node)],
|
||||
table_descr => 'Node storage resources',
|
||||
descriptions => {
|
||||
node => 'The node name',
|
||||
controller => 'The management address to attach/detach new volumes.
|
||||
In the scenario involving multiple controllers, this data must be
|
||||
passed as argument rather than by table value',
|
||||
osvolume => "Specification of what storage to place the node OS image onto. Examples include:
|
||||
localdisk (Install to first non-FC attached disk)
|
||||
usbdisk (Install to first USB mass storage device seen)
|
||||
@@ -284,7 +281,6 @@ storage => {
|
||||
storagepool => 'Name of storage pool where the volume is assigned.',
|
||||
hypervisor => 'Name of the hypervisor where the volume is configured.',
|
||||
fcprange => 'A range of acceptable fibre channels that the volume can use. Examples include: 3B00-3C00;4B00-4C00.',
|
||||
type => 'The plugin used to drive storage configuration (e.g. svc)',
|
||||
volumetag => 'A specific tag used to identify the volume in the autoyast or kickstart template.',
|
||||
comments => 'Any user-written notes.',
|
||||
disable => "Set to 'yes' or '1' to comment out this row.",
|
||||
@@ -393,46 +389,7 @@ ipmi => {
|
||||
descriptions => {
|
||||
node => 'The node name or group name.',
|
||||
bmc => 'The hostname of the BMC adapater.',
|
||||
bmcport => ' In systems with selectable shared/dedicated ethernet ports,
|
||||
this parameter can be used to specify the preferred port. 0
|
||||
means use the shared port, 1 means dedicated, blank is to not
|
||||
assign.
|
||||
|
||||
The following special cases exist for IBM System x servers:
|
||||
|
||||
For x3755 M3 systems, 0 means use the dedicated port, 1 means
|
||||
shared, blank is to not assign.
|
||||
|
||||
For certain systems which have a mezzaine or ML2 adapter, there is a second
|
||||
value to include:
|
||||
|
||||
|
||||
For x3750 M4 (Model 8722):
|
||||
|
||||
|
||||
0 2 1st 1Gbps interface for LOM
|
||||
|
||||
0 0 1st 10Gbps interface for LOM
|
||||
|
||||
0 3 2nd 1Gbps interface for LOM
|
||||
|
||||
0 1 2nd 10Gbps interface for LOM
|
||||
|
||||
|
||||
For x3750 M4 (Model 8752), x3850/3950 X6, dx360 M4, x3550 M4, and x3650 M4:
|
||||
|
||||
|
||||
0 Shared (1st onboard interface)
|
||||
|
||||
1 Dedicated
|
||||
|
||||
2 0 First interface on ML2 or mezzanine adapter
|
||||
|
||||
2 1 Second interface on ML2 or mezzanine adapter
|
||||
|
||||
2 2 Third interface on ML2 or mezzanine adapter
|
||||
|
||||
2 3 Fourth interface on ML2 or mezzanine adapter',
|
||||
bmcport => 'In systems with selectable shared/dedicated ethernet ports, this parameter can be used to specify the preferred port. 0 means use the shared port, 1 means dedicated, blank is to not assign',
|
||||
taggedvlan => 'Have bmcsetup place the BMC on the specified vlan tag on a shared netwirk interface. Some network devices may be incompatible with this option',
|
||||
bmcid => 'Unique identified data used by discovery processes to distinguish known BMCs from unrecognized BMCs',
|
||||
username => 'The BMC userid. If not specified, the key=ipmi row in the passwd table is used as the default.',
|
||||
@@ -575,14 +532,14 @@ nodegroup => {
|
||||
},
|
||||
},
|
||||
nodehm => {
|
||||
cols => [qw(node power mgt cons termserver termport conserver serialport serialspeed serialflow getmac cmdmapping consoleondemand comments disable)],
|
||||
cols => [qw(node power mgt cons termserver termport conserver serialport serialspeed serialflow getmac cmdmapping comments disable)],
|
||||
keys => [qw(node)],
|
||||
tablespace =>'XCATTBS16K',
|
||||
table_desc => "Settings that control how each node's hardware is managed. Typically, an additional table that is specific to the hardware type of the node contains additional info. E.g. the ipmi, mp, and ppc tables.",
|
||||
descriptions => {
|
||||
node => 'The node name or group name.',
|
||||
power => 'The method to use to control the power of the node. If not set, the mgt attribute will be used. Valid values: ipmi, blade, hmc, ivm, fsp, kvm, esx, rhevm. If "ipmi", xCAT will search for this node in the ipmi table for more info. If "blade", xCAT will search for this node in the mp table. If "hmc", "ivm", or "fsp", xCAT will search for this node in the ppc table.',
|
||||
mgt => 'The method to use to do general hardware management of the node. This attribute is used as the default if power or getmac is not set. Valid values: ipmi, blade, hmc, ivm, fsp, bpa, kvm, esx, rhevm. See the power attribute for more details.',
|
||||
power => 'The method to use to control the power of the node. If not set, the mgt attribute will be used. Valid values: ipmi, blade, hmc, ivm, fsp. If "ipmi", xCAT will search for this node in the ipmi table for more info. If "blade", xCAT will search for this node in the mp table. If "hmc", "ivm", or "fsp", xCAT will search for this node in the ppc table.',
|
||||
mgt => 'The method to use to do general hardware management of the node. This attribute is used as the default if power or getmac is not set. Valid values: ipmi, blade, hmc, ivm, fsp, bpa. See the power attribute for more details.',
|
||||
cons => 'The console method. If nodehm.serialport is set, this will default to the nodehm.mgt setting, otherwise it defaults to unused. Valid values: cyclades, mrv, or the values valid for the mgt attribute.',
|
||||
termserver => 'The hostname of the terminal server.',
|
||||
termport => 'The port number on the terminal server that this node is connected to.',
|
||||
@@ -592,13 +549,12 @@ nodehm => {
|
||||
serialflow => "The flow control value of the serial port for this node. For SOL this is typically 'hard'.",
|
||||
getmac => 'The method to use to get MAC address of the node with the getmac command. If not set, the mgt attribute will be used. Valid values: same as values for mgmt attribute.',
|
||||
cmdmapping => 'The fully qualified name of the file that stores the mapping between PCM hardware management commands and xCAT/third-party hardware management commands for a particular type of hardware device. Only used by PCM.',
|
||||
consoleondemand => 'This overrides the value from site.consoleondemand; (0=no, 1=yes). Default is the result from site.consoleondemand.',
|
||||
comments => 'Any user-written notes.',
|
||||
disable => "Set to 'yes' or '1' to comment out this row.",
|
||||
},
|
||||
},
|
||||
nodelist => {
|
||||
cols => [qw(node groups status statustime appstatus appstatustime primarysn hidden updatestatus updatestatustime zonename comments disable)],
|
||||
cols => [qw(node groups status statustime appstatus appstatustime primarysn hidden updatestatus updatestatustime comments disable)],
|
||||
keys => [qw(node)],
|
||||
tablespace =>'XCATTBS32K',
|
||||
table_desc => "The list of all the nodes in the cluster, including each node's current status and what groups it is in.",
|
||||
@@ -611,9 +567,8 @@ nodelist => {
|
||||
appstatustime =>'The date and time when appstatus was updated.',
|
||||
primarysn => 'Not used currently. The primary servicenode, used by this node.',
|
||||
hidden => "Used to hide fsp and bpa definitions, 1 means not show them when running lsdef and nodels",
|
||||
updatestatus => "The current node update status. Valid states are synced, out-of-sync,syncing,failed.",
|
||||
updatestatus => "The current node update status. Valid states are synced out-of-sync,syncing,failed.",
|
||||
updatestatustime => "The date and time when the updatestatus was updated.",
|
||||
zonename => "The name of the zone to which the node is currently assigned. If undefined, then it is not assigned to any zone. ",
|
||||
comments => 'Any user-written notes.',
|
||||
disable => "Set to 'yes' or '1' to comment out this row.",
|
||||
},
|
||||
@@ -636,14 +591,14 @@ nodepos => {
|
||||
},
|
||||
},
|
||||
noderes => {
|
||||
cols => [qw(node servicenode netboot tftpserver tftpdir nfsserver monserver nfsdir installnic primarynic discoverynics cmdinterface xcatmaster current_osimage next_osimage nimserver routenames nameservers proxydhcp comments disable)],
|
||||
cols => [qw(node servicenode netboot tftpserver tftpdir nfsserver monserver nfsdir installnic primarynic discoverynics cmdinterface xcatmaster current_osimage next_osimage nimserver routenames nameservers comments disable)],
|
||||
keys => [qw(node)],
|
||||
tablespace =>'XCATTBS16K',
|
||||
table_desc => 'Resources and settings to use when installing nodes.',
|
||||
descriptions => {
|
||||
node => 'The node name or group name.',
|
||||
servicenode => 'A comma separated list of node names (as known by the management node) that provides most services for this node. The first service node on the list that is accessible will be used. The 2nd node on the list is generally considered to be the backup service node for this node when running commands like snmove.',
|
||||
netboot => 'The type of network booting to use for this node. Valid values: pxe or xnba for x86* architecture, yaboot for POWER architecture, grub2 for RHEL7 on Power. Notice: yaboot is not supported from rhels7 on Power,use grub2 instead',
|
||||
netboot => 'The type of network booting to use for this node. Valid values: pxe or xnba for x86* architecture, yaboot for POWER architecture.',
|
||||
tftpserver => 'The TFTP server for this node (as known by this node). If not set, it defaults to networks.tftpserver.',
|
||||
tftpdir => 'The directory that roots this nodes contents from a tftp and related perspective. Used for NAS offload by using different mountpoints.',
|
||||
nfsserver => 'The NFS or HTTP server for this node (as known by this node).',
|
||||
@@ -659,7 +614,6 @@ noderes => {
|
||||
nimserver => 'Not used for now. The NIM server for this node (as known by this node).',
|
||||
routenames => 'A comma separated list of route names that refer to rows in the routes table. These are the routes that should be defined on this node when it is deployed.',
|
||||
nameservers => 'An optional node/group specific override for name server list. Most people want to stick to site or network defined nameserver configuration.',
|
||||
proxydhcp => 'To specify whether the node supports proxydhcp protocol. Valid values: yes or 1, no or 0. Default value is yes.',
|
||||
comments => 'Any user-written notes.',
|
||||
disable => "Set to 'yes' or '1' to comment out this row.",
|
||||
},
|
||||
@@ -752,7 +706,7 @@ linuximage => {
|
||||
table_desc => 'Information about a Linux operating system image that can be used to deploy cluster nodes.',
|
||||
descriptions => {
|
||||
imagename => 'The name of this xCAT OS image definition.',
|
||||
template => 'The fully qualified name of the template file that will be used to create the OS installer configuration file for stateful installations (e.g. kickstart for RedHat, autoyast for SLES).',
|
||||
template => 'The fully qualified name of the template file that is used to create the kick start file for diskful installation.',
|
||||
boottarget => 'The name of the boottarget definition. When this attribute is set, xCAT will use the kernel, initrd and kernel params defined in the boottarget definition instead of the default.',
|
||||
addkcmdline=> 'User specified arguments to be passed to the kernel. The user arguments are appended to xCAT.s default kernel arguments. This attribute is ignored if linuximage.boottarget is set.',
|
||||
pkglist => 'The fully qualified name of the file that stores the distro packages list that will be included in the image. Make sure that if the pkgs in the pkglist have dependency pkgs, the dependency pkgs should be found in one of the pkgdir',
|
||||
@@ -761,7 +715,7 @@ linuximage => {
|
||||
otherpkgdir => 'The base directory where the non-distro packages are stored.',
|
||||
exlist => 'The fully qualified name of the file that stores the file names and directory names that will be excluded from the image during packimage command. It is used for diskless image only.',
|
||||
postinstall => 'The fully qualified name of the script file that will be run at the end of the genimage command. It is used for diskless image only.',
|
||||
rootimgdir => 'The directory name where the image is stored. It is generally used for diskless image. it also can be used in sysclone environment to specify where the image captured from golden client is stored. in sysclone environment, rootimgdir is generally assigned to some default value by xcat, but you can specify your own store directory. just one thing need to be noticed, wherever you save the image, the name of last level directory must be the name of image. for example, if your image name is testimage and you want to save this image under home directoy, rootimgdir should be assigned to value /home/testimage/',
|
||||
rootimgdir => 'The directory name where the image is stored. It is used for diskless image only.',
|
||||
kerneldir => 'The directory name where the 3rd-party kernel is stored. It is used for diskless image only.',
|
||||
nodebootif => 'The network interface the stateless/statelite node will boot over (e.g. eth0)',
|
||||
otherifce => 'Other network interfaces (e.g. eth1) in the image that should be configured via DHCP',
|
||||
@@ -771,27 +725,12 @@ linuximage => {
|
||||
permission => 'The mount permission of /.statelite directory is used, its default value is 755',
|
||||
dump => qq{The NFS directory to hold the Linux kernel dump file (vmcore) when the node with this image crashes, its format is "nfs://<nfs_server_ip>/<kdump_path>". If you want to use the node's "xcatmaster" (its SN or MN), <nfs_server_ip> can be left blank. For example, "nfs:///<kdump_path>" means the NFS directory to hold the kernel dump file is on the node's SN, or MN if there's no SN.},
|
||||
crashkernelsize => 'the size that assigned to the kdump kernel. If the kernel size is not set, 256M will be the default value.',
|
||||
partitionfile => 'The path of the configuration file which will be used to partition the disk for the node. For stateful osimages,two types of files are supported: "<partition file absolute path>" which contains a partitioning definition that will be inserted directly into the generated autoinst configuration file and must be formatted for the corresponding OS installer (e.g. kickstart for RedHat, autoyast for SLES). "s:<partitioning script absolute path>" which specifies a shell script that will be run from the OS installer configuration file %pre section; the script must write the correct partitioning definition into the file /tmp/partitionfile on the node which will be included into the configuration file during the install process. For statelite osimages, partitionfile should specify "<partition file absolute path>"; see the xCAT Statelite documentation for the xCAT defined format of this configuration file.',
|
||||
partitionfile => 'The path of the configuration file which is used to part the disk for the node. For stateful: two types of value can be set for this attribute. One is "<partition file absolute path>", the content of the partition file must use the corresponding format with the OS type. The other one is "s:<partition file absolute path>", the content of the partition file should be a shell script which must write the partition definition into /tmp/partitionfile on the node. For statelite: the valid value is <partition file absolute path>, refer to the statelite doc for the xCAT defined format of the configuration file.',
|
||||
driverupdatesrc => 'The source of the drivers which need to be loaded during the boot. Two types of driver update source are supported: Driver update disk and Driver rpm package. The value for this attribute should be comma separated sources. Each source should be the format tab:full_path_of_srouce_file. The tab keyword can be: dud (for Driver update disk) and rpm (for driver rpm). If missing the tab, the rpm format is the default. e.g. dud:/install/dud/dd.img,rpm:/install/rpm/d.rpm',
|
||||
comments => 'Any user-written notes.',
|
||||
disable => "Set to 'yes' or '1' to comment out this row.",
|
||||
},
|
||||
},
|
||||
winimage => {
|
||||
cols => [qw(imagename template installto partitionfile winpepath comments disable)],
|
||||
keys => [qw(imagename)],
|
||||
tablespace =>'XCATTBS32K',
|
||||
table_desc => 'Information about a Windows operating system image that can be used to deploy cluster nodes.',
|
||||
descriptions => {
|
||||
imagename => 'The name of this xCAT OS image definition.',
|
||||
template => 'The fully qualified name of the template file that is used to create the windows unattend.xml file for diskful installation.',
|
||||
installto => 'The disk and partition that the Windows will be deployed to. The valid format is <disk>:<partition>. If not set, default value is 0:1 for bios boot mode(legacy) and 0:3 for uefi boot mode; If setting to 1, it means 1:1 for bios boot and 1:3 for uefi boot',
|
||||
partitionfile => 'The path of partition configuration file. Since the partition configuration for bios boot mode and uefi boot mode are different, this configuration file can include both configurations if you need to support both bios and uefi mode. Either way, you must specify the boot mode in the configuration. Example of partition configuration file: [BIOS]xxxxxxx[UEFI]yyyyyyy. To simplify the setting, you also can set installto in partitionfile with section like [INSTALLTO]0:1',
|
||||
winpepath => 'The path of winpe which will be used to boot this image. If the real path is /tftpboot/winboot/winpe1/, the value for winpepath should be set to winboot/winpe1',
|
||||
comments => 'Any user-written notes.',
|
||||
disable => "Set to 'yes' or '1' to comment out this row.",
|
||||
}
|
||||
},
|
||||
passwd => {
|
||||
cols => [qw(key username password cryptmethod authdomain comments disable)],
|
||||
keys => [qw(key username)],
|
||||
@@ -809,11 +748,11 @@ passwd => {
|
||||
policy => {
|
||||
cols => [qw(priority name host commands noderange parameters time rule comments disable)],
|
||||
keys => [qw(priority)],
|
||||
table_desc => 'The policy table in the xCAT database controls who has authority to run specific xCAT operations. It is basically the Access Control List (ACL) for xCAT. It is sorted on the priority field before evaluating.',
|
||||
table_desc => 'The policy table in the xCAT database controls who has authority to run specific xCAT operations. It is basically the Access Control List (ACL) for xCAT.',
|
||||
descriptions => {
|
||||
priority => 'The priority value for this rule. This value is used to identify this policy data object (i.e. this rule) The table is sorted on this field with the lower the number the higher the priority. For example 1.0 is higher priority than 4.1 is higher than 4.9.',
|
||||
priority => 'The priority value for this rule. This value is used to identify this policy data object (i.e. this rule).',
|
||||
name => 'The username that is allowed to perform the commands specified by this rule. Default is "*" (all users).',
|
||||
host => 'The host from which users may issue the commands specified by this rule. Default is "*" (all hosts). Only all or one host is supported',
|
||||
host => 'The host from which users may issue the commands specified by this rule. Default is "*" (all hosts). Only all or one host supported. ',
|
||||
commands => 'The list of commands that this rule applies to. Default is "*" (all commands).',
|
||||
noderange => 'The Noderange that this rule applies to. Default is "*" (all nodes). Not supported with the *def commands.',
|
||||
parameters => 'A regular expression that matches the command parameters (everything except the noderange) that this rule applies to. Default is "*" (all parameters). Not supported with the *def commands.',
|
||||
@@ -827,11 +766,11 @@ postscripts => {
|
||||
cols => [qw(node postscripts postbootscripts comments disable)],
|
||||
keys => [qw(node)],
|
||||
tablespace =>'XCATTBS16K',
|
||||
table_desc => 'The scripts that should be run on each node after installation or diskless boot.',
|
||||
table_desc => ' The scripts that should be run on each node after installation or diskless boot.',
|
||||
descriptions => {
|
||||
node => 'The node name or group name.',
|
||||
postscripts => 'Comma separated list of scripts that should be run on this node after diskfull installation or diskless boot. Each script can take zero or more parameters. For example: "script1 p1 p2,script2,...". xCAT automatically adds the postscripts from the xcatdefaults.postscripts attribute of the table to run first on the nodes after install or diskless boot. For installation of RedHat, CentOS, Fedora, the scripts will be run before the reboot. For installation of SLES, the scripts will be run after the reboot but before the init.d process. For diskless deployment, the scripts will be run at the init.d time, and xCAT will automatically add the list of scripts from the postbootscripts attribute to run after postscripts list. For installation of AIX, the scripts will run after the reboot and acts the same as the postbootscripts attribute. For AIX, use the postbootscripts attribute. Support will be added in the future for the postscripts attribute to run the scripts before the reboot in AIX. ',
|
||||
postbootscripts => 'Comma separated list of scripts that should be run on this node after diskfull installation or diskless boot. Each script can take zero or more parameters. For example: "script1 p1 p2,script2,...". On AIX these scripts are run during the processing of /etc/inittab. On Linux they are run at the init.d time. xCAT automatically adds the scripts in the xcatdefaults.postbootscripts attribute to run first in the list.',
|
||||
postbootscripts => 'Comma separated list of scripts that should be run on thisnode after diskfull installation or diskless boot. Each script can take zero or more parameters. For example: "script1 p1 p2,script2,...". On AIX these scripts are run during the processing of /etc/inittab. On Linux they are run at the init.d time. xCAT automatically adds the scripts in the xcatdefaults.postbootscripts attri bute to run first in the list.',
|
||||
comments => 'Any user-written notes.',
|
||||
disable => "Set to 'yes' or '1' to comment out this row.",
|
||||
},
|
||||
@@ -881,13 +820,13 @@ ppchcp => {
|
||||
},
|
||||
},
|
||||
servicenode => {
|
||||
cols => [qw(node nameserver dhcpserver tftpserver nfsserver conserver monserver ldapserver ntpserver ftpserver nimserver ipforward dhcpinterfaces proxydhcp comments disable)],
|
||||
cols => [qw(node nameserver dhcpserver tftpserver nfsserver conserver monserver ldapserver ntpserver ftpserver nimserver ipforward dhcpinterfaces comments disable)],
|
||||
keys => [qw(node)],
|
||||
tablespace =>'XCATTBS16K',
|
||||
table_desc => 'List of all Service Nodes and services that will be set up on the Service Node.',
|
||||
descriptions => {
|
||||
node => 'The hostname of the service node as known by the Management Node.',
|
||||
nameserver => 'Do we set up DNS on this service node? Valid values: 2, 1, no or 0. If 2, creates named.conf as dns slave, using the management node as dns master, and starts named. If 1, creates named.conf file with forwarding to the management node and starts named. If no or 0, it does not change the current state of the service. ',
|
||||
nameserver => 'Do we set up DNS on this service node? Valid values:yes or 1, no or 0. If yes, creates named.conf file with forwarding to the management node and starts named. If no or 0, it does not change the current state of the service. ',
|
||||
dhcpserver => 'Do we set up DHCP on this service node? Not supported on AIX. Valid values:yes or 1, no or 0. If yes, runs makedhcp -n. If no or 0, it does not change the current state of the service. ',
|
||||
tftpserver => 'Do we set up TFTP on this service node? Not supported on AIX. Valid values:yes or 1, no or 0. If yes, configures and starts atftp. If no or 0, it does not change the current state of the service. ',
|
||||
nfsserver => 'Do we set up file services (HTTP,FTP,or NFS) on this service node? For AIX will only setup NFS, not HTTP or FTP. Valid values:yes or 1, no or 0.If no or 0, it does not change the current state of the service. ',
|
||||
@@ -899,7 +838,6 @@ servicenode => {
|
||||
nimserver => 'Not used. Do we set up a NIM server on this service node? Valid values:yes or 1, no or 0. If no or 0, it does not change the current state of the service.',
|
||||
ipforward => 'Do we set up ip forwarding on this service node? Valid values:yes or 1, no or 0. If no or 0, it does not change the current state of the service.',
|
||||
dhcpinterfaces => 'The network interfaces DHCP server should listen on for the target node. This attribute can be used for management node and service nodes. If defined, it will override the values defined in site.dhcpinterfaces. This is a comma separated list of device names. !remote! indicates a non-local network for relay DHCP. For example: !remote!,eth0,eth1',
|
||||
proxydhcp => 'Do we set up proxydhcp service on this node? valid values: yes or 1, no or 0. If yes, the proxydhcp daemon will be enabled on this node.',
|
||||
|
||||
comments => 'Any user-written notes.',
|
||||
disable => "Set to 'yes' or '1' to comment out this row.",
|
||||
@@ -908,44 +846,35 @@ servicenode => {
|
||||
site => {
|
||||
cols => [qw(key value comments disable)],
|
||||
keys => [qw(key)],
|
||||
table_desc => "Global settings for the whole cluster. This table is different from the \nother tables in that each attribute is just named in the key column, rather \nthan having a separate column for each attribute. The following is a list of \nattributes currently used by xCAT organized into categories.\n",
|
||||
table_desc => "Global settings for the whole cluster. This table is different from the \nother tables in that each attribute is just named in the key column, rather \nthan having a separate column for each attribute. The following is a list of \nthe attributes currently used by xCAT.\n",
|
||||
descriptions => {
|
||||
# Do not put description text past column 88, so it displays well in a 100 char wide window.
|
||||
# ----------------------------------------------------------------------------------|----------
|
||||
key => "Attribute Name: Description\n\n".
|
||||
" ------------\n".
|
||||
"AIX ATTRIBUTES\n".
|
||||
" ------------\n".
|
||||
" nimprime : The name of NIM server, if not set default is the AIX MN.
|
||||
If Linux MN, then must be set for support of mixed cluster (TBD).\n\n".
|
||||
" useSSHonAIX: (yes/1 or no/0). Default is yes. The support for rsh/rcp is deprecated.\n".
|
||||
" useNFSv4onAIX: (yes/1 or no/0). If yes, NFSv4 will be used with NIM. If no,\n".
|
||||
" NFSv3 will be used with NIM. Default is no.\n\n".
|
||||
" -----------------\n".
|
||||
"DATABASE ATTRIBUTES\n".
|
||||
" -----------------\n".
|
||||
" auditskipcmds: List of commands and/or client types that will not be\n".
|
||||
" written to the auditlog table.\n".
|
||||
" auditskipcmds: List of commands and/or client types that will not be written to the auditlog table.\n".
|
||||
" 'ALL' means all cmds will be skipped. If attribute is null, all\n".
|
||||
" commands will be written.\n".
|
||||
" clienttype:web would skip all commands from the web client\n".
|
||||
" For example: tabdump,nodels,clienttype:web \n".
|
||||
" will not log tabdump,nodels and any web client commands.\n\n".
|
||||
" blademaxp: The maximum number of concurrent processes for blade hardware control.\n\n".
|
||||
" cleanupxcatpost: (yes/1 or no/0). Set to 'yes' or '1' to clean up the /xcatpost\n".
|
||||
" directory on the stateless and statelite nodes after the\n".
|
||||
" postscripts are run. Default is no.\n\n".
|
||||
" consoleondemand: When set to 'yes', conserver connects and creates the console\n".
|
||||
" output only when the user opens the console. Default is no on\n".
|
||||
" Linux, yes on AIX.\n\n".
|
||||
" databaseloc: Directory where we create the db instance directory.\n".
|
||||
" Default is /var/lib. Only DB2 is currently supported.\n".
|
||||
" Do not use the directory in the site.installloc or\n".
|
||||
" installdir attribute. This attribute must not be changed\n".
|
||||
" once db2sqlsetup script has been run and DB2 has been setup.\n\n".
|
||||
" excludenodes: A set of comma separated nodes and/or groups that would automatically\n".
|
||||
" be subtracted from any noderange, it can be used for excluding some\n".
|
||||
" failed nodes for any xCAT commands. See the 'noderange' manpage for\n".
|
||||
" details on supported formats.\n\n".
|
||||
" nodestatus: If set to 'n', the nodelist.status column will not be updated during\n".
|
||||
" the node deployment, node discovery and power operations. The default is to update.\n\n".
|
||||
" skiptables: Comma separated list of tables to be skipped by dumpxCATdb\n\n".
|
||||
" -------------\n".
|
||||
"DHCP ATTRIBUTES\n".
|
||||
" -------------\n".
|
||||
" db2installloc: The location which the service nodes should mount for\n".
|
||||
" the db2 code to install. Format is hostname:/path. If hostname is\n".
|
||||
" omitted, it defaults to the management node. Default is /mntdb2.\n\n".
|
||||
" defserialflow: The default serial flow - currently only used by the mknb command.\n\n".
|
||||
" defserialport: The default serial port - currently only used by mknb.\n\n".
|
||||
" defserialspeed: The default serial speed - currently only used by mknb.\n\n".
|
||||
" dhcpinterfaces: The network interfaces DHCP should listen on. If it is the same\n".
|
||||
" for all nodes, use a simple comma-separated list of NICs. To\n".
|
||||
" specify different NICs for different nodes:\n".
|
||||
@@ -958,24 +887,59 @@ site => {
|
||||
" disjointdhcps: If set to '1', the .leases file on a service node only contains\n".
|
||||
" the nodes it manages. The default value is '0'.\n".
|
||||
" '0' value means include all the nodes in the subnet.\n\n".
|
||||
" pruneservices: Whether to enable service pruning when noderm is run (i.e.\n".
|
||||
" removing DHCP entries when noderm is executed)\n\n".
|
||||
" managedaddressmode: The mode of networking configuration during node provision.\n".
|
||||
" If set to 'static', the network configuration will be configured \n".
|
||||
" in static mode based on the node and network definition on MN.\n".
|
||||
" If set to 'dhcp', the network will be configured with dhcp protocol.\n".
|
||||
" The default is 'dhcp'.\n\n".
|
||||
" ------------\n".
|
||||
"DNS ATTRIBUTES\n".
|
||||
" ------------\n".
|
||||
" dnshandler: Name of plugin that handles DNS setup for makedns.\n".
|
||||
" domain: The DNS domain name used for the cluster.\n\n".
|
||||
" ea_primary_hmc: The hostname of the HMC that the Integrated Switch Network\n".
|
||||
" Management Event Analysis should send hardware serviceable\n".
|
||||
" events to for processing and potentially sending to IBM.\n\n".
|
||||
" ea_backup_hmc: The hostname of the HMC that the Integrated Switch Network\n".
|
||||
" Management Event Analysis should send hardware serviceable\n".
|
||||
" events to if the primary HMC is down.\n\n".
|
||||
" enableASMI: (yes/1 or no/0). If yes, ASMI method will be used after fsp-api. If no,\n".
|
||||
" when fsp-api is used, ASMI method will not be used. Default is no.\n\n".
|
||||
" excludenodes: A set of comma separated nodes and/or groups that would automatically\n".
|
||||
" be subtracted from any noderange, it can be used for excluding some\n".
|
||||
" failed nodes for any xCAT commands. See the 'noderange' manpage for\n".
|
||||
" details on supported formats.\n\n".
|
||||
" forwarders: The DNS servers at your site that can provide names outside of the\n".
|
||||
" cluster. The makedns command will configure the DNS on the management\n".
|
||||
" node to forward requests it does not know to these servers.\n".
|
||||
" Note that the DNS servers on the service nodes will ignore this value\n".
|
||||
" and always be configured to forward requests to the management node.\n\n".
|
||||
" fsptimeout: The timeout, in milliseconds, to use when communicating with FSPs.\n\n".
|
||||
" genmacprefix: When generating mac addresses automatically, use this manufacturing\n".
|
||||
" prefix (e.g. 00:11:aa)\n\n".
|
||||
" genpasswords: Automatically generate random passwords for BMCs when configuring\n".
|
||||
" them.\n\n".
|
||||
" httpport: The port number that the booting/installing nodes should contact the\n".
|
||||
" http server on the MN/SN on. It is your responsibility to configure\n".
|
||||
" the http server to listen on that port - xCAT will not do that.\n\n".
|
||||
" installdir: The local directory name used to hold the node deployment packages.\n\n".
|
||||
" installloc: The location from which the service nodes should mount the \n".
|
||||
" deployment packages in the format hostname:/path. If hostname is\n".
|
||||
" omitted, it defaults to the management node. The path must\n".
|
||||
" match the path in the installdir attribute.\n\n".
|
||||
" ipmidispatch: Whether or not to send ipmi hw control operations to the service\n".
|
||||
" node of the target compute nodes. Default is 'y'.\n\n".
|
||||
" hwctrldispatch: Whether or not to send hw control operations to the service\n".
|
||||
" node of the target nodes. Default is 'y'.(At present, this attribute\n".
|
||||
" is only used for IBM Flex System)\n\n".
|
||||
" ipmimaxp: The max # of processes for ipmi hw ctrl. The default is 64. Currently,\n".
|
||||
" this is only used for HP hw control.\n\n".
|
||||
" ipmiretries: The # of retries to use when communicating with BMCs. Default is 3.\n\n".
|
||||
" ipmisdrcache: If set to 'no', then the xCAT IPMI support will not cache locally\n".
|
||||
" the target node's SDR cache to improve performance.\n\n".
|
||||
" ipmitimeout: The timeout to use when communicating with BMCs. Default is 2.\n".
|
||||
" This attribute is currently not used.\n\n".
|
||||
" iscsidir: The path to put the iscsi disks in on the mgmt node.\n\n".
|
||||
" master: The hostname of the xCAT management node, as known by the nodes.\n\n".
|
||||
" maxssh: The max # of SSH connections at any one time to the hw ctrl point for PPC\n".
|
||||
" This parameter doesn't take effect on the rpower command.\n".
|
||||
" It takes effects on other PPC hardware control command\n".
|
||||
" getmacs/rnetboot/rbootseq and so on. Default is 8.\n\n".
|
||||
" mnroutenames: The name of the routes to be setup on the management node.\n".
|
||||
" It is a comma separated list of route names that are defined in the\n".
|
||||
" routes table.\n\n".
|
||||
" nameservers: A comma delimited list of DNS servers that each node in the cluster\n".
|
||||
" should use. This value will end up in the nameserver settings of the\n".
|
||||
" /etc/resolv.conf on each node. It is common (but not required) to set\n".
|
||||
@@ -985,41 +949,18 @@ site => {
|
||||
" \"<xcatmaster>\" to mean the DNS server for each node should be the\n".
|
||||
" node that is managing it (either its service node or the management\n".
|
||||
" node).\n\n".
|
||||
" externaldns: To specify that external dns is used. If externaldns is set to any value\n".
|
||||
" then, makedns command will not start the local nameserver on xCAT MN. \n".
|
||||
" Default is to start the local nameserver.\n\n".
|
||||
" dnsupdaters: The value are \',\' separated string which will be added to the zone config\n".
|
||||
" section. This is an interface for user to add configuration entries to\n".
|
||||
" the zone sections in named.conf.\n\n".
|
||||
" -------------------------\n".
|
||||
"HARDWARE CONTROL ATTRIBUTES\n".
|
||||
" -------------------------\n".
|
||||
" blademaxp: The maximum number of concurrent processes for blade hardware control.\n\n".
|
||||
" ea_primary_hmc: The hostname of the HMC that the Integrated Switch Network\n".
|
||||
" Management Event Analysis should send hardware serviceable\n".
|
||||
" events to for processing and potentially sending to IBM.\n\n".
|
||||
" ea_backup_hmc: The hostname of the HMC that the Integrated Switch Network\n".
|
||||
" Management Event Analysis should send hardware serviceable\n".
|
||||
" events to if the primary HMC is down.\n\n".
|
||||
" enableASMI: (yes/1 or no/0). If yes, ASMI method will be used after fsp-api. If no,\n".
|
||||
" when fsp-api is used, ASMI method will not be used. Default is no.\n\n".
|
||||
" fsptimeout: The timeout, in milliseconds, to use when communicating with FSPs.\n\n".
|
||||
" hwctrldispatch: Whether or not to send hw control operations to the service\n".
|
||||
" node of the target nodes. Default is 'y'.(At present, this attribute\n".
|
||||
" is only used for IBM Flex System)\n\n".
|
||||
" ipmidispatch: Whether or not to send ipmi hw control operations to the service\n".
|
||||
" node of the target compute nodes. Default is 'y'.\n\n".
|
||||
" ipmimaxp: The max # of processes for ipmi hw ctrl. The default is 64. Currently,\n".
|
||||
" this is only used for HP hw control.\n\n".
|
||||
" ipmiretries: The # of retries to use when communicating with BMCs. Default is 3.\n\n".
|
||||
" ipmisdrcache: If set to 'no', then the xCAT IPMI support will not cache locally\n".
|
||||
" the target node's SDR cache to improve performance.\n\n".
|
||||
" ipmitimeout: The timeout to use when communicating with BMCs. Default is 2.\n".
|
||||
" This attribute is currently not used.\n\n".
|
||||
" maxssh: The max # of SSH connections at any one time to the hw ctrl point for PPC\n".
|
||||
" This parameter doesn't take effect on the rpower command.\n".
|
||||
" It takes effects on other PPC hardware control command\n".
|
||||
" getmacs/rnetboot/rbootseq and so on. Default is 8.\n\n".
|
||||
" nimprime : The name of NIM server, if not set default is the AIX MN.
|
||||
If Linux MN, then must be set for support of mixed cluster (TBD).\n\n".
|
||||
" nodestatus: If set to 'n', the nodelist.status column will not be updated during\n".
|
||||
" the node deployment, node discovery and power operations. The default is to update.\n\n".
|
||||
" ntpservers: A comma delimited list of NTP servers for the cluster - often the\n".
|
||||
" xCAT management node.\n\n".
|
||||
" runbootscripts: If set to 'yes' the scripts listed in the postbootscripts\n".
|
||||
" attribute in the osimage and postscripts tables will be run during\n".
|
||||
" each reboot of stateful (diskful) nodes. This attribute has no\n".
|
||||
" effect on stateless and statelite nodes. Please run the following\n" .
|
||||
" command after you change the value of this attribute: \n".
|
||||
" 'updatenode <nodes> -P setuppostbootscripts'\n\n".
|
||||
" syspowerinterval: For system p CECs, this is the number of seconds the rpower\n".
|
||||
" command will wait between performing the action for each CEC.\n".
|
||||
" For system x IPMI servers, this is the number of seconds the\n".
|
||||
@@ -1046,45 +987,15 @@ site => {
|
||||
" ppctimeout: The timeout, in milliseconds, to use when communicating with PPC hw\n".
|
||||
" through HMC. It only takes effect on the hardware control commands\n".
|
||||
" through HMC. Default is 0.\n\n".
|
||||
" snmpc: The snmp community string that xcat should use when communicating with the\n".
|
||||
" switches.\n\n".
|
||||
" ---------------------------\n".
|
||||
"INSTALL/DEPLOYMENT ATTRIBUTES\n".
|
||||
" ---------------------------\n".
|
||||
" cleanupxcatpost: (yes/1 or no/0). Set to 'yes' or '1' to clean up the /xcatpost\n".
|
||||
" directory on the stateless and statelite nodes after the\n".
|
||||
" postscripts are run. Default is no.\n\n".
|
||||
" db2installloc: The location which the service nodes should mount for\n".
|
||||
" the db2 code to install. Format is hostname:/path. If hostname is\n".
|
||||
" omitted, it defaults to the management node. Default is /mntdb2.\n\n".
|
||||
" defserialflow: The default serial flow - currently only used by the mknb command.\n\n".
|
||||
" defserialport: The default serial port - currently only used by mknb.\n\n".
|
||||
" defserialspeed: The default serial speed - currently only used by mknb.\n\n".
|
||||
" genmacprefix: When generating mac addresses automatically, use this manufacturing\n".
|
||||
" prefix (e.g. 00:11:aa)\n\n".
|
||||
" genpasswords: Automatically generate random passwords for BMCs when configuring\n".
|
||||
" them.\n\n".
|
||||
" installdir: The local directory name used to hold the node deployment packages.\n\n".
|
||||
" installloc: The location from which the service nodes should mount the \n".
|
||||
" deployment packages in the format hostname:/path. If hostname is\n".
|
||||
" omitted, it defaults to the management node. The path must\n".
|
||||
" match the path in the installdir attribute.\n\n".
|
||||
" iscsidir: The path to put the iscsi disks in on the mgmt node.\n\n".
|
||||
" mnroutenames: The name of the routes to be setup on the management node.\n".
|
||||
" It is a comma separated list of route names that are defined in the\n".
|
||||
" routes table.\n\n".
|
||||
" runbootscripts: If set to 'yes' the scripts listed in the postbootscripts\n".
|
||||
" attribute in the osimage and postscripts tables will be run during\n".
|
||||
" each reboot of stateful (diskful) nodes. This attribute has no\n".
|
||||
" effect on stateless and statelite nodes. Please run the following\n" .
|
||||
" command after you change the value of this attribute: \n".
|
||||
" 'updatenode <nodes> -P setuppostbootscripts'\n\n".
|
||||
" precreatemypostscripts: (yes/1 or no/0). Default is no. If yes, it will \n".
|
||||
" instruct xCAT at nodeset and updatenode time to query the db once for\n".
|
||||
" all of the nodes passed into the cmd and create the mypostscript file\n".
|
||||
" for each node, and put them in a directory of tftpdir(such as: /tftpboot)\n".
|
||||
" If no, it will not generate the mypostscript file in the tftpdir.\n\n".
|
||||
" setinstallnic: Set the network configuration for installnic to be static.\n\n".
|
||||
" pruneservices: Whether to enable service pruning when noderm is run (i.e.\n".
|
||||
" removing DHCP entries when noderm is executed)\n\n".
|
||||
" rsh: This is no longer used. path to remote shell command for xdsh.\n\n".
|
||||
" rcp: This is no longer used. path to remote copy command for xdcp.\n\n".
|
||||
" sharedtftp: Set to 0 or no, xCAT should not assume the directory\n".
|
||||
" in tftpdir is mounted on all on Service Nodes. Default is 1/yes.\n".
|
||||
" If value is set to a hostname, the directory in tftpdir\n".
|
||||
@@ -1095,31 +1006,18 @@ site => {
|
||||
" shared filesystem is being used across all service nodes.\n".
|
||||
" 'all' means that the management as well as the service nodes\n".
|
||||
" are all using a common shared filesystem. The default is 'no'.\n".
|
||||
" xcatconfdir: Where xCAT config data is (default /etc/xcat).\n\n".
|
||||
" --------------------\n".
|
||||
"REMOTESHELL ATTRIBUTES\n".
|
||||
" --------------------\n".
|
||||
" nodesyncfiledir: The directory on the node, where xdcp will rsync the files\n".
|
||||
" skiptables: Comma separated list of tables to be skipped by dumpxCATdb\n".
|
||||
" SNsyncfiledir: The directory on the Service Node, where xdcp will rsync the files\n".
|
||||
" from the MN that will eventually be rsync'd to the compute nodes.\n\n".
|
||||
" sshbetweennodes: Comma separated list of groups of compute nodes to enable passwordless root \n".
|
||||
" nodesyncfiledir: The directory on the node, where xdcp will rsync the files\n".
|
||||
" snmpc: The snmp community string that xcat should use when communicating with the\n".
|
||||
" switches.\n\n".
|
||||
" sshbetweennodes: Comma separated list of groups to enable passwordless root \n".
|
||||
" ssh during install, or xdsh -K. Default is ALLGROUPS.\n".
|
||||
" Set to NOGROUPS,if you do not wish to enabled any group of compute nodes.\n".
|
||||
" Set to NOGROUPS,if you do not wish to enabled any groups.\n".
|
||||
" Service Nodes are not affected by this attribute\n".
|
||||
" they are always setup with\n".
|
||||
" passwordless root access to nodes and other SN.\n".
|
||||
" If using the zone table, this attribute in not used.\n\n".
|
||||
" -----------------\n".
|
||||
"SERVICES ATTRIBUTES\n".
|
||||
" -----------------\n".
|
||||
" consoleondemand: When set to 'yes', conserver connects and creates the console\n".
|
||||
" output only when the user opens the console. Default is no on\n".
|
||||
" Linux, yes on AIX.\n\n".
|
||||
" httpport: The port number that the booting/installing nodes should contact the\n".
|
||||
" http server on the MN/SN on. It is your responsibility to configure\n".
|
||||
" the http server to listen on that port - xCAT will not do that.\n\n".
|
||||
" ntpservers: A comma delimited list of NTP servers for the cluster - often the\n".
|
||||
" xCAT management node.\n\n".
|
||||
" passwordless root access to nodes and other SN.\n\n".
|
||||
" svloglocal: if set to 1, syslog on the service node will not get forwarded to the\n".
|
||||
" mgmt node.\n\n".
|
||||
" timezone: (e.g. America/New_York)\n\n".
|
||||
@@ -1129,30 +1027,11 @@ site => {
|
||||
" useNmapfromMN: When set to yes, nodestat command should obtain the node status\n".
|
||||
" using nmap (if available) from the management node instead of the\n".
|
||||
" service node. This will improve the performance in a flat network.\n\n".
|
||||
" vsftp: Default is 'n'. If set to 'y', the xcatd on the mn will automatically\n".
|
||||
" bring up vsftpd. (You must manually install vsftpd before this.\n".
|
||||
" This setting does not apply to the service node. For sn\n".
|
||||
" you need to set servicenode.ftpserver=1 if you want xcatd to\n".
|
||||
" bring up vsftpd.\n\n".
|
||||
" -----------------------\n".
|
||||
"VIRTUALIZATION ATTRIBUTES\n".
|
||||
" -----------------------\n".
|
||||
" useSSHonAIX: (yes/1 or no/0). If yes, ssh/scp will be setup and used. If no, rsh/rcp. The support for rsh/rcp is deprecated.\n".
|
||||
" usexhrm: Have xCAT run its xHRM script when booting up KVM guests to set the\n".
|
||||
" virtual network bridge up correctly. See\n".
|
||||
" https://sourceforge.net/apps/mediawiki/xcat/index.php?title=XCAT_Virtualization_with_KVM#Setting_up_a_network_bridge\n\n".
|
||||
" vcenterautojoin: When set to no, the VMWare plugin will not attempt to auto remove\n".
|
||||
" and add hypervisors while trying to perform operations. If users\n".
|
||||
" or tasks outside of xCAT perform the joining this assures xCAT\n".
|
||||
" will not interfere.\n\n".
|
||||
" vmwarereconfigonpower: When set to no, the VMWare plugin will make no effort to\n".
|
||||
" push vm.cpus/vm.memory updates from xCAT to VMWare.\n\n".
|
||||
" persistkvmguests: Keep the kvm definition on the kvm hypervisor when you power off\n".
|
||||
" the kvm guest node. This is useful for you to manually change the \n".
|
||||
" kvm xml definition file in virsh for debugging. Set anything means\n".
|
||||
" enable.\n\n".
|
||||
" --------------------\n".
|
||||
"XCAT DAEMON ATTRIBUTES\n".
|
||||
" --------------------\n".
|
||||
" rsh/rcp will be setup and used on AIX. Default is yes.\n\n".
|
||||
" useflowcontrol: (yes/1 or no/0). If yes, the postscript processing on each node\n".
|
||||
" contacts xcatd on the MN/SN using a lightweight UDP packet to wait\n".
|
||||
" until xcatd is ready to handle the requests associated with\n".
|
||||
@@ -1160,17 +1039,31 @@ site => {
|
||||
" locking out admin interactive use. This value works with the\n".
|
||||
" xcatmaxconnections and xcatmaxbatch attributes. Is not supported on AIX.\n".
|
||||
" If the value is no, nodes sleep for a random time before contacting\n".
|
||||
" xcatd, and retry. The default is no.\n".
|
||||
" xcatd, and retry. On a new install of xcat, this value will be set to yes.\n".
|
||||
" See the following document for details:\n".
|
||||
" Hints_and_Tips_for_Large_Scale_Clusters\n\n".
|
||||
" https://sourceforge.net/apps/mediawiki/xcat/index.php?title=Hints_and_Tips_for_Large_Scale_Clusters\n\n".
|
||||
" useNFSv4onAIX: (yes/1 or no/0). If yes, NFSv4 will be used with NIM. If no,\n".
|
||||
" NFSv3 will be used with NIM. Default is no.\n\n".
|
||||
" vcenterautojoin: When set to no, the VMWare plugin will not attempt to auto remove\n".
|
||||
" and add hypervisors while trying to perform operations. If users\n".
|
||||
" or tasks outside of xCAT perform the joining this assures xCAT\n".
|
||||
" will not interfere.\n\n".
|
||||
" vmwarereconfigonpower: When set to no, the VMWare plugin will make no effort to\n".
|
||||
" push vm.cpus/vm.memory updates from xCAT to VMWare.\n\n".
|
||||
" vsftp: Default is 'n'. If set to 'y', the xcatd on the mn will automatically\n".
|
||||
" bring up vsftpd. (You must manually install vsftpd before this.\n".
|
||||
" This setting does not apply to the service node. For sn\n".
|
||||
" you need to set servicenode.ftpserver=1 if you want xcatd to\n".
|
||||
" bring up vsftpd.\n\n".
|
||||
" xcatconfdir: Where xCAT config data is (default /etc/xcat).\n\n".
|
||||
" xcatmaxconnections: Number of concurrent xCAT protocol requests before requests\n".
|
||||
" begin queueing. This applies to both client command requests\n".
|
||||
" and node requests, e.g. to get postscripts. Default is 64.\n\n".
|
||||
" xcatmaxbatchconnections: Number of concurrent xCAT connections allowed from the nodes.\n".
|
||||
" Value must be less than xcatmaxconnections. Default is 50.\n\n".
|
||||
" xcatdport: The port used by the xcatd daemon for client/server communication.\n\n".
|
||||
" xcatiport: The port used by xcatd to receive install status updates from nodes.\n\n".
|
||||
" xcatsslversion: The ssl version by xcatd. Default is SSLv3.\n\n".
|
||||
" xcatiport: The port used by xcatd to receive install status updates from nodes.\n\n",
|
||||
" xcatsslversion: The ssl version by xcatd. Default is SSLv3.\n\n",
|
||||
" xcatsslciphers: The ssl cipher by xcatd. Default is 3DES.\n\n",
|
||||
value => 'The value of the attribute specified in the "key" column.',
|
||||
comments => 'Any user-written notes.',
|
||||
@@ -1250,19 +1143,6 @@ performance => {
|
||||
disable => "Set to 'yes' or '1' to comment out this row.",
|
||||
},
|
||||
},
|
||||
zone => {
|
||||
cols => [qw(zonename sshkeydir sshbetweennodes defaultzone comments disable)],
|
||||
keys => [qw(zonename)],
|
||||
table_desc => 'Defines a cluster zone for nodes that share root ssh key access to each other.',
|
||||
descriptions => {
|
||||
zonename => 'The name of the zone.',
|
||||
sshkeydir => 'Directory containing the shared root ssh RSA keys.',
|
||||
sshbetweennodes => 'Indicates whether passwordless ssh will be setup between the nodes of this zone. Values are yes/1 or no/0. Default is yes. ',
|
||||
defaultzone => 'If nodes are not assigned to any other zone, they will default to this zone. If value is set to yes or 1.',
|
||||
comments => 'Any user-provided notes.',
|
||||
disable => "Set to 'yes' or '1' to comment out this row.",
|
||||
},
|
||||
},
|
||||
|
||||
eventlog => {
|
||||
cols => [qw(recid eventtime eventtype monitor monnode node application component id severity message rawdata comments disable)],
|
||||
@@ -1399,7 +1279,7 @@ firmware => {
|
||||
},
|
||||
|
||||
nics => {
|
||||
cols => [qw(node nicips nichostnamesuffixes nichostnameprefixes nictypes niccustomscripts nicnetworks nicaliases comments disable)],
|
||||
cols => [qw(node nicips nichostnamesuffixes nictypes niccustomscripts nicnetworks nicaliases comments disable)],
|
||||
keys => [qw(node)],
|
||||
tablespace =>'XCATTBS16K',
|
||||
table_desc => 'Stores NIC details.',
|
||||
@@ -1417,13 +1297,6 @@ nics => {
|
||||
<nic1>!<ext1>|<ext2>,<nic2>!<ext1>|<ext2>,..., for example, eth0!-eth0|-eth0-ipv6,ib0!-ib0|-ib0-ipv6.
|
||||
The xCAT object definition commands support to use nichostnamesuffixes.<nicname> as the sub attributes.
|
||||
Note: According to DNS rules a hostname must be a text string up to 24 characters drawn from the alphabet (A-Z), digits (0-9), minus sign (-),and period (.). When you are specifying "nichostnamesuffixes" or "nicaliases" make sure the resulting hostnames will conform to this naming convention',
|
||||
nichostnameprefixes => 'Comma-separated list of hostname prefixes per NIC.
|
||||
If only one ip address is associated with each NIC:
|
||||
<nic1>!<ext1>,<nic2>!<ext2>,..., for example, eth0!eth0-,ib0!ib-
|
||||
If multiple ip addresses are associcated with each NIC:
|
||||
<nic1>!<ext1>|<ext2>,<nic2>!<ext1>|<ext2>,..., for example, eth0!eth0-|eth0-ipv6i-,ib0!ib-|ib-ipv6-.
|
||||
The xCAT object definition commands support to use nichostnameprefixes.<nicname> as the sub attributes.
|
||||
Note: According to DNS rules a hostname must be a text string up to 24 characters drawn from the alphabet (A-Z), digits (0-9), minus sign (-),and period (.). When you are specifying "nichostnameprefixes" or "nicaliases" make sure the resulting hostnames will conform to this naming convention',
|
||||
nictypes => 'Comma-separated list of NIC types per NIC. <nic1>!<type1>,<nic2>!<type2>, e.g. eth0!Ethernet,ib0!Infiniband. The xCAT object definition commands support to use nictypes.<nicname> as the sub attributes.',
|
||||
niccustomscripts => 'Comma-separated list of custom scripts per NIC. <nic1>!<script1>,<nic2>!<script2>, e.g. eth0!configeth eth0, ib0!configib ib0. The xCAT object definition commands support to use niccustomscripts.<nicname> as the sub attribute
|
||||
.',
|
||||
@@ -1608,32 +1481,8 @@ mic => {
|
||||
disable => "Do not use. tabprune will not work if set to yes or 1",
|
||||
},
|
||||
},
|
||||
hwinv => {
|
||||
cols => [qw(node cputype cpucount memory disksize comments disable)],
|
||||
keys => [qw(node)],
|
||||
table_desc => 'The hareware inventory for the node.',
|
||||
descriptions => {
|
||||
node => 'The node name or group name.',
|
||||
cputype => 'The cpu model name for the node.',
|
||||
cpucount => 'The number of cpus for the node.',
|
||||
memory => 'The size of the memory for the node in MB.',
|
||||
disksize => 'The size of the disks for the node in GB.',
|
||||
comments => 'Any user-provided notes.',
|
||||
disable => "Set to 'yes' or '1' to comment out this row.",
|
||||
},
|
||||
},
|
||||
token => {
|
||||
cols => [qw(tokenid username expire comments disable)],
|
||||
keys => [qw(tokenid)],
|
||||
table_desc => 'The token of users for authentication.',
|
||||
descriptions => {
|
||||
tokenid => 'It is a UUID as an unified identify for the user.',
|
||||
username => 'The user name.',
|
||||
expire => 'The expire time for this token.',
|
||||
comments => 'Any user-provided notes.',
|
||||
disable => "Set to 'yes' or '1' to comment out this row.",
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
); # end of tabspec definition
|
||||
|
||||
|
||||
@@ -1711,7 +1560,6 @@ foreach my $tabname (keys(%xCAT::ExtTab::ext_tabspec)) {
|
||||
rack => { attrs => [], attrhash => {}, objkey => 'rackname' },
|
||||
osdistro=> { attrs => [], attrhash => {}, objkey => 'osdistroname' },
|
||||
osdistroupdate=> { attrs => [], attrhash => {}, objkey => 'osupdatename' },
|
||||
zone=> { attrs => [], attrhash => {}, objkey => 'zonename' },
|
||||
|
||||
);
|
||||
|
||||
@@ -1780,11 +1628,6 @@ my @nodeattrs = (
|
||||
tabentry => 'noderes.monserver',
|
||||
access_tabentry => 'noderes.node=attr:node',
|
||||
},
|
||||
{attr_name => 'supportproxydhcp',
|
||||
tabentry => 'noderes.proxydhcp',
|
||||
access_tabentry => 'noderes.node=attr:node',
|
||||
},
|
||||
|
||||
{attr_name => 'kernel',
|
||||
tabentry => 'bootparams.kernel',
|
||||
access_tabentry => 'bootparams.node=attr:node',
|
||||
@@ -1853,10 +1696,6 @@ my @nodeattrs = (
|
||||
{attr_name => 'setupipforward',
|
||||
tabentry => 'servicenode.ipforward',
|
||||
access_tabentry => 'servicenode.node=attr:node',
|
||||
},
|
||||
{attr_name => 'setupproxydhcp',
|
||||
tabentry => 'servicenode.proxydhcp',
|
||||
access_tabentry => 'servicenode.node=attr:node',
|
||||
},
|
||||
# - moserver not used yet
|
||||
# {attr_name => 'setupmonserver',
|
||||
@@ -1977,10 +1816,6 @@ my @nodeattrs = (
|
||||
{attr_name => 'serialflow',
|
||||
tabentry => 'nodehm.serialflow',
|
||||
access_tabentry => 'nodehm.node=attr:node',
|
||||
},
|
||||
{attr_name => 'consoleondemand',
|
||||
tabentry => 'nodehm.consoleondemand',
|
||||
access_tabentry => 'nodehm.node=attr:node',
|
||||
},
|
||||
##################
|
||||
# vpd table #
|
||||
@@ -2342,10 +2177,6 @@ my @nodeattrs = (
|
||||
tabentry => 'nics.nichostnamesuffixes',
|
||||
access_tabentry => 'nics.node=attr:node',
|
||||
},
|
||||
{attr_name => 'nichostnameprefixes',
|
||||
tabentry => 'nics.nichostnameprefixes',
|
||||
access_tabentry => 'nics.node=attr:node',
|
||||
},
|
||||
{attr_name => 'nictypes',
|
||||
tabentry => 'nics.nictypes',
|
||||
access_tabentry => 'nics.node=attr:node',
|
||||
@@ -2399,14 +2230,6 @@ my @nodeattrs = (
|
||||
tabentry => 'storage.osvolume',
|
||||
access_tabentry => 'storage.node=attr:node',
|
||||
},
|
||||
{attr_name => 'storagcontroller',
|
||||
tabentry => 'storage.controller',
|
||||
access_tabentry => 'storage.node=attr:node',
|
||||
},
|
||||
{attr_name => 'storagetype',
|
||||
tabentry => 'storage.type',
|
||||
access_tabentry => 'storage.node=attr:node',
|
||||
},
|
||||
######################
|
||||
# vm table #
|
||||
######################
|
||||
@@ -2629,26 +2452,7 @@ my @nodeattrs = (
|
||||
tabentry => 'mic.powermgt',
|
||||
access_tabentry => 'mic.node=attr:node',
|
||||
},
|
||||
#####################
|
||||
## hwinv table #
|
||||
#####################
|
||||
{attr_name => 'cputype',
|
||||
tabentry => 'hwinv.cputype',
|
||||
access_tabentry => 'hwinv.node=attr:node',
|
||||
},
|
||||
{attr_name => 'cpucount',
|
||||
tabentry => 'hwinv.cpucount',
|
||||
access_tabentry => 'hwinv.node=attr:node',
|
||||
},
|
||||
{attr_name => 'memory',
|
||||
tabentry => 'hwinv.memory',
|
||||
access_tabentry => 'hwinv.node=attr:node',
|
||||
},
|
||||
{attr_name => 'disksize',
|
||||
tabentry => 'hwinv.disksize',
|
||||
access_tabentry => 'hwinv.node=attr:node',
|
||||
},
|
||||
|
||||
|
||||
); # end of @nodeattrs that applies to both nodes and groups
|
||||
|
||||
|
||||
@@ -2698,11 +2502,7 @@ my @nodeattrs = (
|
||||
{attr_name => 'updatestatustime',
|
||||
tabentry => 'nodelist.updatestatustime',
|
||||
access_tabentry => 'nodelist.node=attr:node',
|
||||
},
|
||||
{attr_name => 'zonename',
|
||||
tabentry => 'nodelist.zonename',
|
||||
access_tabentry => 'nodelist.node=attr:node',
|
||||
},
|
||||
},
|
||||
{attr_name => 'usercomment',
|
||||
tabentry => 'nodelist.comments',
|
||||
access_tabentry => 'nodelist.node=attr:node',
|
||||
@@ -2907,29 +2707,6 @@ push(@{$defspec{node}->{'attrs'}}, @nodeattrs);
|
||||
access_tabentry => 'linuximage.imagename=attr:imagename',
|
||||
},
|
||||
####################
|
||||
# winimage table#
|
||||
####################
|
||||
{attr_name => 'template',
|
||||
only_if => 'imagetype=windows',
|
||||
tabentry => 'winimage.template',
|
||||
access_tabentry => 'winimage.imagename=attr:imagename',
|
||||
},
|
||||
{attr_name => 'installto',
|
||||
only_if => 'imagetype=windows',
|
||||
tabentry => 'winimage.installto',
|
||||
access_tabentry => 'winimage.imagename=attr:imagename',
|
||||
},
|
||||
{attr_name => 'partitionfile',
|
||||
only_if => 'imagetype=windows',
|
||||
tabentry => 'winimage.partitionfile',
|
||||
access_tabentry => 'winimage.imagename=attr:imagename',
|
||||
},
|
||||
{attr_name => 'winpepath',
|
||||
only_if => 'imagetype=windows',
|
||||
tabentry => 'winimage.winpepath',
|
||||
access_tabentry => 'winimage.imagename=attr:imagename',
|
||||
},
|
||||
####################
|
||||
# nimimage table#
|
||||
####################
|
||||
{attr_name => 'nimtype',
|
||||
@@ -3156,31 +2933,6 @@ push(@{$defspec{node}->{'attrs'}}, @nodeattrs);
|
||||
access_tabentry => 'rack.rackname=attr:rackname',
|
||||
},
|
||||
);
|
||||
####################
|
||||
# zone table #
|
||||
####################
|
||||
@{$defspec{zone}->{'attrs'}} = (
|
||||
{attr_name => 'zonename',
|
||||
tabentry => 'zone.zonename',
|
||||
access_tabentry => 'zone.zonename=attr:zonename',
|
||||
},
|
||||
{attr_name => 'sshkeydir',
|
||||
tabentry => 'zone.sshkeydir',
|
||||
access_tabentry => 'zone.zonename=attr:zonename',
|
||||
},
|
||||
{attr_name => 'sshbetweennodes',
|
||||
tabentry => 'zone.sshbetweennodes',
|
||||
access_tabentry => 'zone.zonename=attr:zonename',
|
||||
},
|
||||
{attr_name => 'defaultzone',
|
||||
tabentry => 'zone.defaultzone',
|
||||
access_tabentry => 'zone.zonename=attr:zonename',
|
||||
},
|
||||
{attr_name => 'usercomment',
|
||||
tabentry => 'zone.comments',
|
||||
access_tabentry => 'zone.zonename=attr:zonename',
|
||||
},
|
||||
);
|
||||
#########################
|
||||
# route data object #
|
||||
#########################
|
||||
|
||||
Executable → Regular
-2
@@ -163,8 +163,6 @@ sub isServiceReq
|
||||
if (($value eq "1") || ($value eq "YES"))
|
||||
{
|
||||
$servicehash->{$service} = "1";
|
||||
} elsif ($value eq "2") {
|
||||
$servicehash->{$service} = "2";
|
||||
} else {
|
||||
$servicehash->{$service} = "0";
|
||||
}
|
||||
|
||||
@@ -4013,8 +4013,7 @@ sub output_table {
|
||||
Example:
|
||||
|
||||
my $tabh = xCAT::Table->new($table);
|
||||
my $recs=$tabh->getEntries("recid"); # returns row with recid max value in database
|
||||
# and the row with the min value.
|
||||
my $recs=$tabh->getMAXMINEntries("recid");
|
||||
|
||||
Comments:
|
||||
none
|
||||
@@ -4032,14 +4031,13 @@ sub getMAXMINEntries
|
||||
my $rets;
|
||||
my $query;
|
||||
my $xcatcfg=get_xcatcfg();
|
||||
|
||||
# delimit the disable column based on the DB
|
||||
my $disable= &delimitcol("disable");
|
||||
my $qstring;
|
||||
if ($xcatcfg =~ /^DB2:/) { # for DB2
|
||||
if ($xcatcfg =~ /^DB2:/) { # for DB2
|
||||
$qstring = "SELECT MAX (\"$attr\") FROM " . $self->{tabname} . " WHERE " . $disable . " is NULL or " . $disable . " in ('0','no','NO','No','nO')";
|
||||
} else {
|
||||
$qstring = "SELECT MAX($attr) FROM " . $self->{tabname} . " WHERE " . $disable . " is NULL or " . $disable . " in ('0','no','NO','No','nO')";
|
||||
$qstring = "SELECT MAX($attr) FROM " . $self->{tabname} . " WHERE " . $disable . " is NULL or " . $disable . " in ('0','no','NO','No','nO')";
|
||||
}
|
||||
$query = $self->{dbh}->prepare($qstring);
|
||||
|
||||
@@ -4060,10 +4058,10 @@ sub getMAXMINEntries
|
||||
}
|
||||
}
|
||||
$query->finish();
|
||||
if ($xcatcfg =~ /^DB2:/) { # for DB2
|
||||
if ($xcatcfg =~ /^DB2:/) { # for DB2
|
||||
$qstring = "SELECT MIN (\"$attr\") FROM " . $self->{tabname} . " WHERE " . $disable . " is NULL or " . $disable . " in ('0','no','NO','No','nO')";
|
||||
} else {
|
||||
$qstring = "SELECT MIN($attr) FROM " . $self->{tabname} . " WHERE " . $disable . " is NULL or " . $disable . " in ('0','no','NO','No','nO')";
|
||||
$qstring = "SELECT MIN($attr) FROM " . $self->{tabname} . " WHERE " . $disable . " is NULL or " . $disable . " in ('0','no','NO','No','nO')";
|
||||
}
|
||||
$query = $self->{dbh}->prepare($qstring);
|
||||
|
||||
@@ -4078,10 +4076,11 @@ sub getMAXMINEntries
|
||||
} else {
|
||||
$rets->{"min"} = $data->{$_};
|
||||
}
|
||||
last; # better be only one value for min
|
||||
last; # better be only one value for min
|
||||
}
|
||||
}
|
||||
return $rets;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
|
||||
Executable → Regular
+44
-325
@@ -19,7 +19,6 @@ if ($^O =~ /^aix/i) {
|
||||
use lib "$::XCATROOT/lib/perl";
|
||||
use strict;
|
||||
require xCAT::Table;
|
||||
require xCAT::Zone;
|
||||
use File::Path;
|
||||
#-----------------------------------------------------------------------
|
||||
|
||||
@@ -272,7 +271,7 @@ sub bldnonrootSSHFiles
|
||||
Error:
|
||||
0=good, 1=error
|
||||
Example:
|
||||
xCAT::TableUtils->setupSSH(@target_nodes,$expecttimeout);
|
||||
xCAT::TableUtils->setupSSH(@target_nodes);
|
||||
Comments:
|
||||
Does not setup known_hosts. Assumes automatically
|
||||
setup by SSH ( ssh config option StrictHostKeyChecking no should
|
||||
@@ -336,21 +335,21 @@ sub setupSSH
|
||||
|
||||
$::REMOTE_SHELL = "/usr/bin/ssh";
|
||||
my $rsp = {};
|
||||
|
||||
|
||||
# Get the home directory
|
||||
my $home = xCAT::Utils->getHomeDir($from_userid);
|
||||
$ENV{'DSH_FROM_USERID_HOME'} = $home;
|
||||
|
||||
if ($from_userid eq "root")
|
||||
{
|
||||
|
||||
# make the directory to hold keys to transfer to the nodes
|
||||
if (!-d $SSHdir)
|
||||
{
|
||||
mkpath("$SSHdir", { mode => 0755 });
|
||||
}
|
||||
|
||||
# generates new keys for root, if they do not already exist ~/.ssh
|
||||
|
||||
# generates new keys for root, if they do not already exist
|
||||
# nodes not used on this option but in there to preserve the interface
|
||||
my $rc=
|
||||
xCAT::RemoteShellExp->remoteshellexp("k",$::CALLBACK,$::REMOTE_SHELL,$n_str,$expecttimeout);
|
||||
@@ -375,10 +374,7 @@ else
|
||||
fi
|
||||
mkdir -p \$dest_dir
|
||||
cat /tmp/$to_userid/.ssh/authorized_keys >> \$home/.ssh/authorized_keys 2>&1
|
||||
cat /tmp/$to_userid/.ssh/id_rsa.pub >> \$home/.ssh/authorized_keys 2>&1
|
||||
rm -f \$home/.ssh/id_rsa 2>&1
|
||||
cp /tmp/$to_userid/.ssh/id_rsa \$home/.ssh/id_rsa 2>&1
|
||||
cp /tmp/$to_userid/.ssh/id_rsa.pub \$home/.ssh/id_rsa.pub 2>&1
|
||||
chmod 0600 \$home/.ssh/id_* 2>&1
|
||||
rm -f /tmp/$to_userid/.ssh/* 2>&1
|
||||
rmdir \"/tmp/$to_userid/.ssh\"
|
||||
@@ -390,7 +386,6 @@ rmdir \"/tmp/$to_userid\" \n";
|
||||
my $auth_key2=0;
|
||||
if ($from_userid eq "root")
|
||||
{
|
||||
# this will put the root/.ssh/id_rsa.pub key in the authorized keys file to put on the node
|
||||
my $rc = xCAT::TableUtils->cpSSHFiles($SSHdir);
|
||||
if ($rc != 0)
|
||||
{ # error
|
||||
@@ -423,46 +418,50 @@ rmdir \"/tmp/$to_userid\" \n";
|
||||
xCAT::TableUtils->bldnonrootSSHFiles($from_userid);
|
||||
}
|
||||
|
||||
# send the keys
|
||||
# send the keys to the nodes for root or some other id
|
||||
#
|
||||
# This environment variable determines whether to setup
|
||||
# node to node ssh
|
||||
# The nodes must be checked against the site.sshbetweennodes attribute
|
||||
# For root user and not to devices only to nodes
|
||||
if (($from_userid eq "root") && (!($ENV{'DEVICETYPE'}))) {
|
||||
# Need to check if nodes are in a zone.
|
||||
my @zones;
|
||||
my $tab = xCAT::Table->new("zone");
|
||||
if ($tab)
|
||||
my $enablenodes;
|
||||
my $disablenodes;
|
||||
my @nodelist= split(",", $n_str);
|
||||
foreach my $n (@nodelist)
|
||||
{
|
||||
# if we have zones, need to send the zone keys to each node in the zone
|
||||
my @attribs = ("zonename");
|
||||
@zones = $tab->getAllAttribs(@attribs);
|
||||
$tab->close();
|
||||
} else {
|
||||
$rsp->{data}->[0] = "Could not open zone table.\n";
|
||||
xCAT::MsgUtils->message("E", $rsp, $::CALLBACK);
|
||||
return 1;
|
||||
}
|
||||
# check for zones, key send is different if zones defined or not
|
||||
|
||||
if (@zones) { # we have zones defined
|
||||
my $rc = xCAT::TableUtils->sendkeysTOzones($ref_nodes,$expecttimeout);
|
||||
if ($rc != 0)
|
||||
{
|
||||
$rsp->{data}->[0] = "Error sending ssh keys to the zones.\n";
|
||||
xCAT::MsgUtils->message("E", $rsp, $::CALLBACK);
|
||||
exit 1;
|
||||
|
||||
my $enablessh=xCAT::TableUtils->enablessh($n);
|
||||
if ($enablessh == 1) {
|
||||
$enablenodes .= $n;
|
||||
$enablenodes .= ",";
|
||||
} else {
|
||||
$disablenodes .= $n;
|
||||
$disablenodes .= ",";
|
||||
}
|
||||
} else { # no zones
|
||||
|
||||
# if no zone table defined, do it the old way , keys are in ~/.ssh
|
||||
my $rc = xCAT::TableUtils->sendkeysNOzones($ref_nodes,$expecttimeout);
|
||||
|
||||
}
|
||||
my $cmd;
|
||||
if ($enablenodes) { # node on list to setup nodetonodessh
|
||||
chop $enablenodes; # remove last comma
|
||||
$ENV{'DSH_ENABLE_SSH'} = "YES";
|
||||
my $rc=xCAT::RemoteShellExp->remoteshellexp("s",$::CALLBACK,"/usr/bin/ssh",$enablenodes,$expecttimeout);
|
||||
if ($rc != 0)
|
||||
{
|
||||
$rsp->{data}->[0] = "Error sending ssh keys to the nodes.\n";
|
||||
xCAT::MsgUtils->message("E", $rsp, $::CALLBACK);
|
||||
{
|
||||
$rsp->{data}->[0] = "remoteshellexp failed sending keys to enablenodes.";
|
||||
xCAT::MsgUtils->message("E", $rsp, $::CALLBACK);
|
||||
|
||||
}
|
||||
}
|
||||
if ($disablenodes) { # node on list to setup nodetonodessh
|
||||
chop $disablenodes; # remove last comma
|
||||
my $rc=xCAT::RemoteShellExp->remoteshellexp("s",$::CALLBACK,"/usr/bin/ssh",$disablenodes,$expecttimeout);
|
||||
if ($rc != 0)
|
||||
{
|
||||
$rsp->{data}->[0] = "remoteshellexp failed sending keys to disablenodes.";
|
||||
xCAT::MsgUtils->message("E", $rsp, $::CALLBACK);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
} else { # from user is not root or it is a device , always send private key
|
||||
$ENV{'DSH_ENABLE_SSH'} = "YES";
|
||||
my $rc=xCAT::RemoteShellExp->remoteshellexp("s",$::CALLBACK,"/usr/bin/ssh",$n_str,$expecttimeout);
|
||||
@@ -504,235 +503,6 @@ rmdir \"/tmp/$to_userid\" \n";
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
|
||||
=head3 sendkeysNOzones
|
||||
|
||||
Transfers the ssh keys
|
||||
for the root id on the nodes no zones
|
||||
key from ~/.ssh site.sshbetweennodes honored
|
||||
|
||||
|
||||
Arguments:
|
||||
Array of nodes
|
||||
Timeout for expect call (optional)
|
||||
Returns:
|
||||
|
||||
Env Variables: $DSH_FROM_USERID, $DSH_TO_USERID, $DSH_REMOTE_PASSWORD
|
||||
the ssh keys are transferred from the $DSH_FROM_USERID to the $DSH_TO_USERID
|
||||
on the node(s). The DSH_REMOTE_PASSWORD and the DSH_FROM_USERID
|
||||
must be obtained by
|
||||
the calling script or from the xdsh client
|
||||
|
||||
Globals:
|
||||
$::XCATROOT , $::CALLBACK
|
||||
Error:
|
||||
0=good, 1=error
|
||||
Example:
|
||||
xCAT::TableUtils->sendkeysNOzones($ref_nodes,$expecttimeout);
|
||||
Comments:
|
||||
Does not setup known_hosts. Assumes automatically
|
||||
setup by SSH ( ssh config option StrictHostKeyChecking no should
|
||||
be set in the ssh config file).
|
||||
|
||||
=cut
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
sub sendkeysNOzones
|
||||
{
|
||||
my ($class, $ref_nodes,$expecttimeout) = @_;
|
||||
my @nodes=$ref_nodes;
|
||||
my $enablenodes;
|
||||
my $disablenodes;
|
||||
my $n_str = $nodes[0];
|
||||
my @nodelist= split(",", $n_str);
|
||||
my $rsp = ();
|
||||
foreach my $n (@nodelist)
|
||||
{
|
||||
my $enablessh=xCAT::TableUtils->enablessh($n);
|
||||
if ($enablessh == 1) {
|
||||
$enablenodes .= $n;
|
||||
$enablenodes .= ",";
|
||||
} else {
|
||||
$disablenodes .= $n;
|
||||
$disablenodes .= ",";
|
||||
}
|
||||
|
||||
}
|
||||
if ($enablenodes) { # node on list to setup nodetonodessh
|
||||
chop $enablenodes; # remove last comma
|
||||
$ENV{'DSH_ENABLE_SSH'} = "YES";
|
||||
# send the keys to the nodes
|
||||
my $rc=xCAT::RemoteShellExp->remoteshellexp("s",$::CALLBACK,"/usr/bin/ssh",$enablenodes,$expecttimeout);
|
||||
if ($rc != 0)
|
||||
{
|
||||
$rsp->{data}->[0] = "remoteshellexp failed sending keys to enablenodes.";
|
||||
xCAT::MsgUtils->message("E", $rsp, $::CALLBACK);
|
||||
|
||||
}
|
||||
}
|
||||
if ($disablenodes) { # node on list to disable nodetonodessh
|
||||
chop $disablenodes; # remove last comma
|
||||
# send the keys to the nodes
|
||||
my $rc=xCAT::RemoteShellExp->remoteshellexp("s",$::CALLBACK,"/usr/bin/ssh",$disablenodes,$expecttimeout);
|
||||
if ($rc != 0)
|
||||
{
|
||||
$rsp->{data}->[0] = "remoteshellexp failed sending keys to disablenodes.";
|
||||
xCAT::MsgUtils->message("E", $rsp, $::CALLBACK);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
#--------------------------------------------------------------------------------
|
||||
|
||||
=head3 sendkeysTOzones
|
||||
|
||||
Transfers the ssh keys
|
||||
for the root id on the nodes using the zone table.
|
||||
If in a zone, then root ssh keys for the node will be taken from the zones ssh keys not ~/.ssh
|
||||
zones are only supported on nodes that are not a service node.
|
||||
Also for the call to RemoteShellExp, we must group the nodes that are in the same zone
|
||||
|
||||
|
||||
Arguments:
|
||||
Array of nodes
|
||||
Timeout for expect call (optional)
|
||||
Returns:
|
||||
|
||||
Env Variables: $DSH_FROM_USERID, $DSH_TO_USERID, $DSH_REMOTE_PASSWORD
|
||||
the ssh keys are transferred from the $DSH_FROM_USERID to the $DSH_TO_USERID
|
||||
on the node(s). The DSH_REMOTE_PASSWORD and the DSH_FROM_USERID
|
||||
must be obtained by
|
||||
the calling script or from the xdsh client
|
||||
|
||||
Globals:
|
||||
$::XCATROOT , $::CALLBACK
|
||||
Error:
|
||||
0=good, 1=error
|
||||
Example:
|
||||
xCAT::TableUtils->sendkeysTOzones($ref_nodes,$expecttimeout);
|
||||
Comments:
|
||||
Does not setup known_hosts. Assumes automatically
|
||||
setup by SSH ( ssh config option StrictHostKeyChecking no should
|
||||
be set in the ssh config file).
|
||||
|
||||
=cut
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
sub sendkeysTOzones
|
||||
{
|
||||
my ($class, $ref_nodes,$expecttimeout) = @_;
|
||||
my @nodes=$ref_nodes;
|
||||
my $n_str = $nodes[0];
|
||||
@nodes= split(",", $n_str);
|
||||
my $rsp = ();
|
||||
my $cmd;
|
||||
my $roothome = xCAT::Utils->getHomeDir("root");
|
||||
my $zonehash =xCAT::Zone->getzoneinfo($::CALLBACK,\@nodes);
|
||||
foreach my $zonename (keys %$zonehash) {
|
||||
# build list of nodes
|
||||
my $zonenodelist="";
|
||||
foreach my $node (@{$zonehash->{$zonename}->{nodes}}) {
|
||||
$zonenodelist .= $node;
|
||||
$zonenodelist .= ",";
|
||||
|
||||
}
|
||||
$zonenodelist =~ s/,$//; # remove last comma
|
||||
# if any nodes defined for the zone
|
||||
if ($zonenodelist) {
|
||||
# check to see if we enable passwordless ssh between the nodes
|
||||
if (!(defined($zonehash->{$zonename}->{sshbetweennodes}))||
|
||||
(($zonehash->{$zonename}->{sshbetweennodes} =~ /^yes$/i )
|
||||
|| ($zonehash->{$zonename}->{sshbetweennodes} eq "1"))) {
|
||||
|
||||
$ENV{'DSH_ENABLE_SSH'} = "YES";
|
||||
} else {
|
||||
delete $ENV{'DSH_ENABLE_SSH'}; # do not enable passwordless ssh
|
||||
}
|
||||
# point to the ssh keys to send for this zone
|
||||
my $keydir = $zonehash->{$zonename}->{sshkeydir} ;
|
||||
|
||||
# check to see if the id_rsa and id_rsa.pub key is in the directory
|
||||
my $key="$keydir/id_rsa";
|
||||
my $key2="$keydir/id_rsa.pub";
|
||||
# Check to see if empty
|
||||
if (!(-e $key)) {
|
||||
my $rsp = {};
|
||||
$rsp->{error}->[0] =
|
||||
"The $key file does not exist for $zonename. Need to use chzone to regenerate the keys.";
|
||||
xCAT::MsgUtils->message("E", $rsp, $::CALLBACK, 1);
|
||||
return 1;
|
||||
}
|
||||
if (!(-e $key2)) {
|
||||
my $rsp = {};
|
||||
$rsp->{error}->[0] =
|
||||
"The $key2 file does not exist for $zonename. Need to use chzone to regenerate the keys.";
|
||||
xCAT::MsgUtils->message("E", $rsp, $::CALLBACK, 1);
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
# now put copy.sh in the zone directory from ~/.ssh
|
||||
my $rootkeydir="$roothome/.ssh";
|
||||
if ($rootkeydir ne $keydir) { # the zone keydir is not the same as ~/.ssh.
|
||||
$cmd="cp $rootkeydir/copy.sh $keydir";
|
||||
xCAT::Utils->runcmd($cmd, 0);
|
||||
if ($::RUNCMD_RC != 0)
|
||||
{
|
||||
my $rsp = {};
|
||||
$rsp->{error}->[0] =
|
||||
"Could not copy copy.sh to the zone key dir";
|
||||
xCAT::MsgUtils->message("E", $rsp, $::CALLBACK);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
# Also create $keydir/tmp and put root's id_rsa.pub (in authorized_keys) for the transfer
|
||||
$cmd="mkdir -p $keydir/tmp";
|
||||
xCAT::Utils->runcmd($cmd, 0);
|
||||
if ($::RUNCMD_RC != 0)
|
||||
{
|
||||
my $rsp = {};
|
||||
$rsp->{error}->[0] =
|
||||
"Could not mkdir the zone $keydir/tmp";
|
||||
xCAT::MsgUtils->message("E", $rsp, $::CALLBACK);
|
||||
return 1;
|
||||
}
|
||||
# create authorized_keys file
|
||||
if (xCAT::Utils->isMN()) { # if on Management Node
|
||||
$cmd = " cp $roothome/.ssh/id_rsa.pub $keydir/tmp/authorized_keys";
|
||||
} else { # SN
|
||||
$cmd = " cp $roothome/.ssh/authorized_keys $keydir/tmp/authorized_keys";
|
||||
}
|
||||
xCAT::Utils->runcmd($cmd, 0);
|
||||
if ($::RUNCMD_RC != 0)
|
||||
{
|
||||
$rsp->{data}->[0] = "$cmd failed.\n";
|
||||
xCAT::MsgUtils->message("E", $rsp, $::CALLBACK);
|
||||
return (1);
|
||||
}
|
||||
else
|
||||
{
|
||||
chmod 0600, "$keydir/.ssh/tmp/authorized_keys";
|
||||
}
|
||||
# strip off .ssh
|
||||
my ($newkeydir,$ssh) = (split(/\.ssh/, $keydir));
|
||||
$ENV{'DSH_ZONE_SSHKEYS'} =$newkeydir ;
|
||||
# send the keys to the nodes
|
||||
my $rc=xCAT::RemoteShellExp->remoteshellexp("s",$::CALLBACK,"/usr/bin/ssh",
|
||||
$zonenodelist,$expecttimeout);
|
||||
if ($rc != 0)
|
||||
{
|
||||
$rsp = {};
|
||||
$rsp->{data}->[0] = "remoteshellexp failed sending keys to $zonename.";
|
||||
xCAT::MsgUtils->message("E", $rsp, $::CALLBACK);
|
||||
|
||||
}
|
||||
} # end nodes in the zone
|
||||
|
||||
} # end for each zone
|
||||
|
||||
return (0);
|
||||
}
|
||||
#--------------------------------------------------------------------------------
|
||||
|
||||
=head3 cpSSHFiles
|
||||
|
||||
Builds authorized_keyfiles for root
|
||||
@@ -1177,9 +947,7 @@ sub getAppStatus
|
||||
my ($class, $nodes_ref, $application) = @_;
|
||||
my @nodes = @$nodes_ref;
|
||||
|
||||
# FIXME: why autocommit matters for a read-only subroutine getNodesAttribs?
|
||||
# but could not get the appstatus without the autocommit=0
|
||||
my $nltab = xCAT::Table->new('nodelist', -autocommit => 0);
|
||||
my $nltab = xCAT::Table->new('nodelist');
|
||||
my $nodeappstat = $nltab->getNodesAttribs(\@nodes,['appstatus']);
|
||||
|
||||
my $ret_nodeappstat;
|
||||
@@ -1826,8 +1594,8 @@ sub enableSSH
|
||||
|
||||
} else {
|
||||
# if not a service node we need to check, before enabling
|
||||
if (keys %$groups_hash) { # not empty
|
||||
if ($groups_hash->{ALLGROUPS} == 1)
|
||||
if (defined($groups_hash)) {
|
||||
if ($groups_hash->{ALLGROUPS} == 1)
|
||||
{
|
||||
$enablessh=1;
|
||||
}
|
||||
@@ -2001,7 +1769,7 @@ sub updatenodegroups {
|
||||
}
|
||||
}
|
||||
my ($ent) = $tabhd->getNodeAttribs($node, ['groups']);
|
||||
my @list = ();
|
||||
my @list = qw(all);
|
||||
if (defined($ent) and $ent->{groups}) {
|
||||
push @list, split(/,/,$ent->{groups});
|
||||
}
|
||||
@@ -2015,54 +1783,5 @@ sub updatenodegroups {
|
||||
@list = keys %saw;
|
||||
$tabhd->setNodeAttribs($node, {groups=>join(",",@list)});
|
||||
}
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
=head3 rmnodegroups
|
||||
remove groups from the group attribute for the specified node
|
||||
|
||||
Arguments:
|
||||
node
|
||||
tabhd: the handler of 'nodelist' table,
|
||||
groups: the groups that need to be removed.
|
||||
Can be an array or string.
|
||||
Globals:
|
||||
none
|
||||
Error:
|
||||
Example:
|
||||
xCAT::TableUtils->rmnodegroups($node, $tab, $groups);
|
||||
|
||||
=cut
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
sub rmnodegroups {
|
||||
my ($class, $node, $tabhd, $groups) = @_;
|
||||
my ($ent) = $tabhd->getNodeAttribs($node, ['groups']);
|
||||
my @definedgroups;
|
||||
my @removegroups;
|
||||
my @newgroups;
|
||||
if (defined($ent) and $ent->{groups}) {
|
||||
push @definedgroups, split(/,/,$ent->{groups});
|
||||
}
|
||||
if (ref($groups) eq 'ARRAY') {
|
||||
push @removegroups, @$groups;
|
||||
} else {
|
||||
push @removegroups, split(/,/,$groups);
|
||||
}
|
||||
# take out any groups that match the input list of groups to remove
|
||||
foreach my $dgrp (@definedgroups){
|
||||
if (grep(/^$dgrp$/, @removegroups)) { # is the group to be removed
|
||||
next;
|
||||
} else { # keep this group
|
||||
push @newgroups,$dgrp;
|
||||
}
|
||||
}
|
||||
my %saw;
|
||||
@saw{@newgroups} = ();
|
||||
@newgroups = keys %saw;
|
||||
|
||||
$tabhd->setNodeAttribs($node, {groups=>join(",",@newgroups)});
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
+8
-16
@@ -18,9 +18,8 @@ use xCAT::Utils;
|
||||
my %usage = (
|
||||
"rnetboot" =>
|
||||
"Usage: rnetboot <noderange> [-s net|hd] [-F] [-f] [-V|--verbose] [-m table.colum==expectedstatus] [-m table.colum==expectedstatus...] [-r <retrycount>] [-t <timeout>]
|
||||
rnetboot [-h|--help|-v|--version]
|
||||
zVM specific:
|
||||
rnetboot <noderange> [ipl= address]",
|
||||
rnetboot <noderange> [ipl= address]
|
||||
rnetboot [-h|--help|-v|--version]",
|
||||
"rpower" =>
|
||||
"Usage: rpower <noderange> [--nodeps] [on|onstandby|off|suspend|reset|stat|state|boot] [-V|--verbose] [-m table.colum==expectedstatus][-m table.colum==expectedstatus...] [-r <retrycount>] [-t <timeout>]
|
||||
rpower [-h|--help|-v|--version]
|
||||
@@ -28,10 +27,8 @@ my %usage = (
|
||||
rpower <noderange> [boot] [ -c <path to iso> ]
|
||||
PPC (with IVM or HMC) specific:
|
||||
rpower <noderange> [--nodeps] [of] [-V|--verbose]
|
||||
CEC (with HMC) specific:
|
||||
rpower <noderange> [on|off|reset|boot|onstandby]
|
||||
LPAR(with HMC) specific:
|
||||
rpower <noderange> [on|off|reset|stat|state|boot|of|sms|softoff]
|
||||
PPC (HMC) specific:
|
||||
rpower <noderange> [onstandby] [-V|--verbose]
|
||||
CEC(using Direct FSP Management) specific:
|
||||
rpower <noderange> [on|onstandby|off|stat|state|lowpower|resetsp]
|
||||
Frame(using Direct FSP Management) specific:
|
||||
@@ -134,7 +131,7 @@ my %usage = (
|
||||
textid=<*>|
|
||||
frame=<*>|
|
||||
ntp=<[ntp],[ip],[frequency],[v3]>
|
||||
FSP/CEC (using ASM Interface) Specific:
|
||||
FSP/BPA Common:
|
||||
rspconfig <noderange> [autopower|iocap|decfg|memdecfg|procdecfg|time|date|spdump|sysdump|network|hostname]
|
||||
rspconfig <noderange> autopower=<enable|disable>|
|
||||
iocap=<enable|disable>|
|
||||
@@ -210,7 +207,6 @@ my %usage = (
|
||||
mkvm noderange [--full]
|
||||
mkvm noderange [vmcpus=min/req/max] [vmmemory=min/req/max]
|
||||
[vmphyslots=drc_index1,drc_index2...] [vmothersetting=hugepage:N,bsr:N]
|
||||
[vmnics=vlan1,vlan2] [vmstorage=<N|viosnode:slotid>] [--vios]
|
||||
For KVM
|
||||
mkvm noderange -m|--master mastername -s|--size disksize -f|--force
|
||||
For zVM
|
||||
@@ -225,7 +221,7 @@ my %usage = (
|
||||
lsvm <noderange> [-a|--all]
|
||||
PPC (using Direct FSP Management) specific:
|
||||
lsvm <noderange> [-l|--long] --p775
|
||||
lsvm <noderange>
|
||||
lsvm <noderange>
|
||||
zVM specific:
|
||||
lsvm noderange
|
||||
lsvm noderange --getnetworknames
|
||||
@@ -244,11 +240,7 @@ my %usage = (
|
||||
chvm <noderange> --p775 -i <id> [-m <memory_interleaving>] -r <partition_rule>
|
||||
chvm <noderange> [lparname=<*|name>]
|
||||
chvm <noderange> [vmcpus=min/req/max] [vmmemory=min/req/max]
|
||||
[vmothersetting=hugepage:N,bsr:N]
|
||||
[add_physlots=drc_index1,drc_index2...]
|
||||
[add_vmnics=vlan1,vlan2] [add_vmstorage=<N|viosnode:slotid>] [--vios]
|
||||
chvm <noderange> [del_physlots=drc_index1,drc_index2...]
|
||||
chvm <noderange> [del_vadapter=slotid]
|
||||
[vmphyslots=drc_index1,drc_index2...] [vmothersetting=hugepage:N,bsr:N]
|
||||
VMware specific:
|
||||
chvm <noderange> [-a size][-d disk][-p disk][--resize disk=size][--cpus count][--mem memory]
|
||||
zVM specific:
|
||||
@@ -285,7 +277,7 @@ my %usage = (
|
||||
"lsslp" =>
|
||||
"Usage: lsslp [-h|--help|-v|--version]
|
||||
lsslp [<noderange>][-V|--verbose][-i ip[,ip..]][-w][-r|-x|-z][-n][-I][-s FRAME|CEC|MM|IVM|RSA|HMC|CMM|IMM2|FSP]
|
||||
[-u] [--range IPranges][-t tries][--vpdtable][-C counts][-T timeout]",
|
||||
[-t tries][--vpdtable][-C counts][-T timeout]",
|
||||
"rflash" =>
|
||||
"Usage:
|
||||
rflash [ -h|--help|-v|--version]
|
||||
|
||||
Executable → Regular
+17
-727
@@ -120,38 +120,6 @@ This program module file, is a set of utilities used by xCAT commands.
|
||||
|
||||
#-------------------------------------------------------------
|
||||
|
||||
=head3 clroptionvars
|
||||
|
||||
- use this routine to clear GetOptions global option variables
|
||||
before calling GetOptions.
|
||||
|
||||
- this may be needed because a "command" may be called twice
|
||||
from the same process - and global options may have been
|
||||
set the first time through. (ex. from a plugin using runxcmd() )
|
||||
|
||||
- should really avoid global vars but this provides a quick fix
|
||||
for now
|
||||
|
||||
ex. my $rc = xCAT::Utils->clroptionvars($::opt1, $::opt2 ...)
|
||||
|
||||
=cut
|
||||
|
||||
#-------------------------------------------------------
|
||||
sub clroptionvars
|
||||
{
|
||||
# skip the class arg and set the rest to undef
|
||||
my $skippedclass=0;
|
||||
foreach (@_) {
|
||||
if ($skippedclass) {
|
||||
$_ = undef;
|
||||
}
|
||||
$skippedclass=1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------
|
||||
|
||||
=head3 genUUID
|
||||
Returns an RFC 4122 compliant UUIDv4 or UUIDv1
|
||||
Arguments:
|
||||
@@ -977,9 +945,13 @@ sub runcmd
|
||||
if ($::VERBOSE)
|
||||
{
|
||||
# get this systems name as known by xCAT management node
|
||||
my $hostname = `/bin/hostname`;
|
||||
chomp $hostname;
|
||||
my $msg="Running command on $hostname: $cmd";
|
||||
my $Sname = xCAT::InstUtils->myxCATname();
|
||||
my $msg;
|
||||
if ($Sname) {
|
||||
$msg = "Running command on $Sname: $cmd";
|
||||
} else {
|
||||
$msg="Running command: $cmd";
|
||||
}
|
||||
|
||||
if ($::CALLBACK){
|
||||
my $rsp = {};
|
||||
@@ -1370,30 +1342,11 @@ sub runxcmd_output
|
||||
}
|
||||
}
|
||||
}
|
||||
if (defined($node->{error}))
|
||||
{
|
||||
if (ref(\($node->{error}->[0])) eq 'SCALAR')
|
||||
{
|
||||
$desc = $desc . ": " . $node->{error}->[0];
|
||||
}
|
||||
}
|
||||
if (defined($node->{errorcode}))
|
||||
{
|
||||
if (ref(\($node->{errorcode}->[0])) eq 'SCALAR')
|
||||
{
|
||||
$::RUNCMD_RC |= $node->{errorcode}->[0];
|
||||
}
|
||||
}
|
||||
push @$::xcmd_outref, $desc;
|
||||
}
|
||||
if (defined($resp->{error}))
|
||||
{
|
||||
if (ref($resp->{error}) eq 'ARRAY')
|
||||
{
|
||||
push @$::xcmd_outref, @{$resp->{error}};
|
||||
} else {
|
||||
push @$::xcmd_outref, $resp->{error};
|
||||
}
|
||||
}
|
||||
if (defined($resp->{errorcode}))
|
||||
{
|
||||
@@ -1879,7 +1832,8 @@ sub get_image_name
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
=head3 StartService
|
||||
Supports AIX only, use startservice for Linux
|
||||
Supports AIX and Linux as long as the service is registered with
|
||||
lssrc or startsrc.
|
||||
Used by the service node plugin (AAsn.pm) to start requested services.
|
||||
Checks to see if the input service is already started. If it is started
|
||||
it stops and starts the service. Otherwise
|
||||
@@ -1899,9 +1853,7 @@ sub get_image_name
|
||||
Example:
|
||||
if (xCAT::Utils->startService("named") { ...}
|
||||
Comments:
|
||||
this subroutine is deprecated for Linux,
|
||||
will be used as an internal function to process AIX service,
|
||||
for linux, use xCAT::Utils->startservice instead
|
||||
none
|
||||
|
||||
=cut
|
||||
|
||||
@@ -2552,12 +2504,6 @@ sub check_deployment_monitoring_settings()
|
||||
($attr, $val) = split /=~/,$m,2;
|
||||
$val =~ s/^\///;
|
||||
$val =~ s/\/$//;
|
||||
} elsif ($m =~ /^[^=]*!=/) {
|
||||
($attr, $val) = split /!=/,$m,2;
|
||||
} elsif ($m =~ /^[^=]*!~/) {
|
||||
($attr, $val) = split /!~/,$m,2;
|
||||
$val =~ s/^\///;
|
||||
$val =~ s/\/$//;
|
||||
} else {
|
||||
my $rsp={};
|
||||
$rsp->{data}->[0] = "Invalid string \"$m\" specified with -m flag";
|
||||
@@ -3196,7 +3142,7 @@ sub isSELINUX
|
||||
Input:
|
||||
array of nodes in the noderange
|
||||
Example:
|
||||
my @mn=xCAT::Utils->noderangecontainsMN($noderange);
|
||||
my $mn=xCAT::Utils->noderangecontainsMN($noderange);
|
||||
Comments:
|
||||
=cut
|
||||
|
||||
@@ -3340,7 +3286,7 @@ sub filter_nodes{
|
||||
push @{$mpnodes}, @ngpbmc;
|
||||
} else {
|
||||
push @{$bmcnodes}, @ngpbmc;
|
||||
}
|
||||
}
|
||||
} elsif($cmd eq "getmacs") {
|
||||
if (@args && (grep /^-D$/,@args)) {
|
||||
push @{$fspnodes}, @ngpfsp;
|
||||
@@ -3405,8 +3351,8 @@ sub filter_nostatusupdate{
|
||||
if ($nodetypetab) {
|
||||
$nttabdata = $nodetypetab->getNodesAttribs(\@allnodes, ['node', 'os']);
|
||||
$nodetypetab->close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#filter out the nodes which support the node provision status feedback
|
||||
my @nodesfiltered=();
|
||||
if(exists $inref->{$::STATUS_INSTALLING}){
|
||||
@@ -3416,7 +3362,7 @@ sub filter_nostatusupdate{
|
||||
@{$inref->{$::STATUS_INSTALLING}}=@nodesfiltered;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@nodesfiltered=();
|
||||
if(exists $inref->{$::STATUS_NETBOOTING}){
|
||||
map{ if($nttabdata->{$_}->[0]->{os} !~ /(fedora|rh|centos|sles|ubuntu)/) {push @nodesfiltered,$_;} } @{$inref->{$::STATUS_NETBOOTING}};
|
||||
@@ -3425,663 +3371,7 @@ sub filter_nostatusupdate{
|
||||
@{$inref->{$::STATUS_NETBOOTING}}=@nodesfiltered;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
sub version_cmp {
|
||||
my $ver_a = shift;
|
||||
if ($ver_a =~ /xCAT::Utils/)
|
||||
{
|
||||
$ver_a = shift;
|
||||
}
|
||||
my $ver_b = shift;
|
||||
my @array_a = ($ver_a =~ /([-.]|\d+|[^-.\d]+)/g);
|
||||
my @array_b = ($ver_b =~ /([-.]|\d+|[^-.\d]+)/g);
|
||||
|
||||
my ($a, $b);
|
||||
my $len_a = @array_a;
|
||||
my $len_b = @array_b;
|
||||
my $len = $len_a;
|
||||
if ( $len_b < $len_a ) {
|
||||
$len = $len_b;
|
||||
}
|
||||
for ( my $i = 0; $i < $len; $i++ ) {
|
||||
$a = $array_a[$i];
|
||||
$b = $array_b[$i];
|
||||
if ($a eq $b) {
|
||||
next;
|
||||
} elsif ( $a eq '-' ) {
|
||||
return -1;
|
||||
} elsif ( $b eq '-') {
|
||||
return 1;
|
||||
} elsif ( $a eq '.' ) {
|
||||
return -1;
|
||||
} elsif ( $b eq '.' ) {
|
||||
return 1;
|
||||
} elsif ($a =~ /^\d+$/ and $b =~ /^\d+$/) {
|
||||
if ($a =~ /^0/ || $b =~ /^0/) {
|
||||
return ($a cmp $b);
|
||||
} else {
|
||||
return ($a <=> $b);
|
||||
}
|
||||
} else {
|
||||
$a = uc $a;
|
||||
$b = uc $b;
|
||||
return ($a cmp $b);
|
||||
}
|
||||
}
|
||||
return ( $len_a <=> $len_b )
|
||||
}
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
=head3 fullpathbin
|
||||
returns the full path of a specified binary executable file
|
||||
Arguments:
|
||||
string of the bin file name
|
||||
Returns:
|
||||
string of the full path name of the binary executable file
|
||||
Globals:
|
||||
none
|
||||
Error:
|
||||
string of the bin file name in the argument
|
||||
Example:
|
||||
my $CHKCONFIG = xCAT::Utils->fullpathbin("chkconfig");
|
||||
Comments:
|
||||
none
|
||||
|
||||
=cut
|
||||
#--------------------------------------------------------------------------------
|
||||
sub fullpathbin
|
||||
{
|
||||
my $bin=shift;
|
||||
if( $bin =~ /xCAT::Utils/)
|
||||
{
|
||||
$bin=shift;
|
||||
}
|
||||
|
||||
my @paths= ("/bin","/usr/bin","/sbin","/usr/sbin");
|
||||
my $fullpath=$bin;
|
||||
|
||||
foreach my $path (@paths)
|
||||
{
|
||||
if (-x $path.'/'.$bin)
|
||||
{
|
||||
$fullpath= $path.'/'.$bin;
|
||||
last;
|
||||
}
|
||||
}
|
||||
|
||||
return $fullpath;
|
||||
}
|
||||
#--------------------------------------------------------------------------------
|
||||
|
||||
=head3 gettimezone
|
||||
returns the name of the timezone defined on the Linux distro.
|
||||
This routine was written to replace the use of /etc/sysconfig/clock which in no
|
||||
longer supported on future Linux releases such as RHEL7. It is suppose to be a routine
|
||||
that can find the timezone on any Linux OS or AIX.
|
||||
Arguments:
|
||||
none
|
||||
Returns:
|
||||
Name of timezone, for example US/Eastern
|
||||
Globals:
|
||||
none
|
||||
Error:
|
||||
None
|
||||
Example:
|
||||
my $timezone = xCAT::Utils->gettimezone();
|
||||
Comments:
|
||||
none
|
||||
=cut
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
sub gettimezone
|
||||
{
|
||||
my ($class) = @_;
|
||||
|
||||
my $tz;
|
||||
if (xCAT::Utils->isAIX()) {
|
||||
$tz= $ENV{'TZ'};
|
||||
} else { # all linux
|
||||
my $localtime = "/etc/localtime";
|
||||
my $zoneinfo = "/usr/share/zoneinfo";
|
||||
my $cmd = "find $zoneinfo -xtype f -exec cmp -s $localtime {} \\; -print | grep -v posix | grep -v SystemV | grep -v right | grep -v localtime ";
|
||||
my $zone_result = xCAT::Utils->runcmd("$cmd", 0);
|
||||
if ($::RUNCMD_RC != 0)
|
||||
{
|
||||
$tz="Could not determine timezone checksum";
|
||||
return $tz;
|
||||
}
|
||||
my @zones = split /\n/, $zone_result;
|
||||
|
||||
$zones[0] =~ s/$zoneinfo\///;
|
||||
if (!$zones[0]) { # if we still did not get one, then default
|
||||
$tz = `cat /etc/timezone`;
|
||||
chomp $tz;
|
||||
} else {
|
||||
$tz=$zones[0];
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
return $tz;
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
|
||||
=head3 servicemap
|
||||
returns the name of service unit(for systemd) or service daemon(for SYSVinit).
|
||||
Arguments:
|
||||
$svcname: the name of the service
|
||||
$svcmgrtype: the service manager type:
|
||||
0: SYSVinit
|
||||
1: systemd
|
||||
2: upstart
|
||||
Returns:
|
||||
the name of service unit or service daemon
|
||||
undef on fail
|
||||
Globals:
|
||||
none
|
||||
Error:
|
||||
None
|
||||
Example:
|
||||
my $svc = xCAT::Utils->servicemap($svcname,1);
|
||||
Comments:
|
||||
none
|
||||
=cut
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
sub servicemap{
|
||||
my $svcname=shift;
|
||||
if( $svcname =~ /xCAT::Utils/)
|
||||
{
|
||||
$svcname=shift;
|
||||
}
|
||||
|
||||
my $svcmgrtype=shift;
|
||||
|
||||
|
||||
#hash structure:
|
||||
#"service name $svcname" =>{
|
||||
#"service manager name(SYSVinit/systemd) $svcmgrtype"
|
||||
#=> ["list of possible service file names for the specified $svcname under the specified $svcmgrtype "]
|
||||
# }
|
||||
#
|
||||
#
|
||||
# if there are more than 1 possible service names for a service among
|
||||
# different os distributions and os releases, the service should be
|
||||
# specified in %svchash with structure
|
||||
# (general service name) => {list of possible service names}
|
||||
#
|
||||
my %svchash=(
|
||||
"dhcp" => ["dhcp3-server","dhcpd","isc-dhcp-server"],
|
||||
"nfs" => ["nfsserver","nfs-server","nfs","nfs-kernel-server"],
|
||||
"named" => ["named","bind9"],
|
||||
"syslog" => ["syslog","syslogd","rsyslog"],
|
||||
"firewall" => ["iptables","firewalld","SuSEfirewall2_setup","ufw"],
|
||||
"http" => ["apache2","httpd"],
|
||||
"ntpserver" =>["ntpd","ntp"],
|
||||
"mysql" => ["mysqld","mysql"],
|
||||
);
|
||||
|
||||
my $path=undef;
|
||||
my $postfix="";
|
||||
my $retdefault=$svcname;
|
||||
if($svcmgrtype == 0){
|
||||
$path="/etc/init.d/";
|
||||
}elsif ($svcmgrtype == 1){
|
||||
$path="/usr/lib/systemd/system/";
|
||||
$postfix=".service";
|
||||
# $retdefault=$svcname.".service";
|
||||
}elsif ($svcmgrtype == 2){
|
||||
$path="/etc/init/";
|
||||
$postfix=".conf";
|
||||
}
|
||||
|
||||
|
||||
my $ret=undef;
|
||||
if($svchash{$svcname}){
|
||||
foreach my $file (@{$svchash{$svcname}}){
|
||||
if(-e $path.$file.$postfix ){
|
||||
$ret=$file;
|
||||
last;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
if(-e $path.$retdefault.$postfix){
|
||||
$ret=$retdefault;
|
||||
}
|
||||
}
|
||||
|
||||
return $ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
|
||||
=head3 startservice
|
||||
start a service
|
||||
Arguments:
|
||||
service name
|
||||
Returns:
|
||||
0 on success
|
||||
nonzero otherwise
|
||||
Globals:
|
||||
none
|
||||
Error:
|
||||
none
|
||||
Example:
|
||||
xCAT::Utils->startservice("nfs");
|
||||
Comments:
|
||||
none
|
||||
=cut
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
sub startservice{
|
||||
my $svcname=shift;
|
||||
if( $svcname =~ /xCAT::Utils/)
|
||||
{
|
||||
$svcname=shift;
|
||||
}
|
||||
|
||||
my $cmd="";
|
||||
#for Systemd
|
||||
my $svcunit=undef;
|
||||
#for sysVinit
|
||||
my $svcd=undef;
|
||||
#for upstart
|
||||
my $svcjob=undef;
|
||||
|
||||
$svcunit=servicemap($svcname,1);
|
||||
$svcjob=servicemap($svcname,2);
|
||||
$svcd=servicemap($svcname,0);
|
||||
if($svcunit)
|
||||
{
|
||||
$cmd="systemctl start $svcunit";
|
||||
}
|
||||
elsif( $svcjob )
|
||||
{
|
||||
$cmd="initctl start $svcjob";
|
||||
}
|
||||
elsif( $svcd )
|
||||
{
|
||||
$cmd="service $svcd start";
|
||||
}
|
||||
|
||||
#print "$cmd\n";
|
||||
if( $cmd eq "" )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
#xCAT::Utils->runcmd($cmd, -1); # do not use runcmd (backtics), must use system to not fork
|
||||
system($cmd);
|
||||
$::RUNCMD_RC=$?;
|
||||
return $::RUNCMD_RC;
|
||||
|
||||
}
|
||||
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
|
||||
=head3 stopservice
|
||||
stop a service
|
||||
Arguments:
|
||||
service name
|
||||
Returns:
|
||||
0 on success
|
||||
nonzero otherwise
|
||||
Globals:
|
||||
none
|
||||
Error:
|
||||
none
|
||||
Example:
|
||||
xCAT::Utils->stopservice("nfs");
|
||||
Comments:
|
||||
none
|
||||
=cut
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
sub stopservice{
|
||||
my $svcname=shift;
|
||||
if( $svcname =~ /xCAT::Utils/)
|
||||
{
|
||||
$svcname=shift;
|
||||
}
|
||||
|
||||
my $cmd="";
|
||||
my $svcunit=undef;
|
||||
my $svcd=undef;
|
||||
my $svcjob=undef;
|
||||
|
||||
$svcunit=servicemap($svcname,1);
|
||||
$svcjob=servicemap($svcname,2);
|
||||
$svcd=servicemap($svcname,0);
|
||||
if($svcunit)
|
||||
{
|
||||
$cmd="systemctl stop $svcunit";
|
||||
}
|
||||
elsif( $svcjob )
|
||||
{
|
||||
$cmd="initctl status $svcjob |grep stop; if [ \"\$?\" != \"0\" ]; then initctl stop $svcjob ; fi";
|
||||
}
|
||||
elsif( $svcd )
|
||||
{
|
||||
$cmd="service $svcd stop";
|
||||
}
|
||||
|
||||
|
||||
#print "$cmd\n";
|
||||
if( $cmd eq "" )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
#xCAT::Utils->runcmd($cmd, -1); # do not use runcmd (backtics), must use system to not fork
|
||||
system($cmd);
|
||||
$::RUNCMD_RC=$?;
|
||||
return $::RUNCMD_RC;
|
||||
}
|
||||
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
|
||||
=head3 restartservice
|
||||
restart a service
|
||||
Arguments:
|
||||
service name
|
||||
Returns:
|
||||
0 on success
|
||||
nonzero otherwise
|
||||
Globals:
|
||||
none
|
||||
Error:
|
||||
none
|
||||
Example:
|
||||
xCAT::Utils->restartservice("nfs");
|
||||
Comments:
|
||||
none
|
||||
=cut
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
sub restartservice{
|
||||
my $svcname=shift;
|
||||
if( $svcname =~ /xCAT::Utils/)
|
||||
{
|
||||
$svcname=shift;
|
||||
}
|
||||
|
||||
my $cmd="";
|
||||
my $svcunit=undef;
|
||||
my $svcd=undef;
|
||||
my $svcjob=undef;
|
||||
|
||||
$svcunit=servicemap($svcname,1);
|
||||
$svcjob=servicemap($svcname,2);
|
||||
$svcd=servicemap($svcname,0);
|
||||
if($svcunit)
|
||||
{
|
||||
$cmd="systemctl restart $svcunit";
|
||||
}
|
||||
elsif( $svcd )
|
||||
{
|
||||
$cmd="service $svcd restart";
|
||||
}
|
||||
elsif( $svcjob )
|
||||
{
|
||||
$cmd="initctl status $svcjob |grep stop; if [ \"\$?\" != \"0\" ]; then initctl restart $svcjob ; else initctl start $svcjob; fi";
|
||||
}
|
||||
|
||||
#print "$cmd\n";
|
||||
if( $cmd eq "" )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
xCAT::Utils->runcmd($cmd, -1);
|
||||
return $::RUNCMD_RC;
|
||||
}
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
|
||||
=head3 checkservicestatus
|
||||
returns theservice status.
|
||||
Arguments:
|
||||
$svcname: the name of the service
|
||||
$outputoption[optional]:
|
||||
the output option
|
||||
1: return a hashref with the keys:"retcode","retmsg"
|
||||
otherwise: return retcode only
|
||||
Returns:
|
||||
undef on fail
|
||||
a hashref if $outputoption is 1,the hash structure is:
|
||||
{"retcode"=>(status code, 0 for running/active,1 for stopped/inactive,2 for failed)
|
||||
"retmsg" =>(status string, running/active/stopped/inactive/failed)
|
||||
}
|
||||
the status code otherwise
|
||||
|
||||
Globals:
|
||||
none
|
||||
Error:
|
||||
None
|
||||
Example:
|
||||
my $ret = xCAT::Utils-checkservicestatus($svcname,1);
|
||||
my $retcode = xCAT::Utils-checkservicestatus($svcname);
|
||||
Comments:
|
||||
none
|
||||
=cut
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
sub checkservicestatus{
|
||||
my $svcname=shift;
|
||||
if( $svcname =~ /xCAT::Utils/)
|
||||
{
|
||||
$svcname=shift;
|
||||
}
|
||||
|
||||
my $outputoption=shift;
|
||||
|
||||
my $cmd="";
|
||||
my $svcunit=undef;
|
||||
my $svcd=undef;
|
||||
my $svcjob=undef;
|
||||
my %ret;
|
||||
|
||||
$svcunit=servicemap($svcname,1);
|
||||
$svcjob=servicemap($svcname,2);
|
||||
$svcd=servicemap($svcname,0);
|
||||
my $output=undef;
|
||||
|
||||
if($svcunit)
|
||||
{
|
||||
#for systemd, parse the output since it is formatted
|
||||
$cmd="systemctl show --property=ActiveState $svcunit|awk -F '=' '{print \$2}'";
|
||||
$output=xCAT::Utils->runcmd($cmd, -1);
|
||||
if($output =~ /^active$/i){
|
||||
$ret{retcode}=0;
|
||||
}elsif($output =~ /^failed$/i){
|
||||
$ret{retcode}=2;
|
||||
|
||||
}elsif($output =~ /^inactive$/i){
|
||||
$ret{retcode}=1;
|
||||
}
|
||||
}
|
||||
elsif ( $svcjob )
|
||||
{
|
||||
#for upstart, parse the output
|
||||
$cmd="initctl status $svcjob";
|
||||
$output=xCAT::Utils->runcmd($cmd, -1);
|
||||
if($output =~ /waiting/i){
|
||||
$ret{retcode}=2;
|
||||
}elsif($output =~ /running/i){
|
||||
$ret{retcode}=0;
|
||||
}
|
||||
|
||||
}
|
||||
elsif( $svcd )
|
||||
{
|
||||
#for SYSVinit, check the return value since the "service" command output is confused
|
||||
$cmd="service $svcd status";
|
||||
$output=xCAT::Utils->runcmd($cmd, -1);
|
||||
$ret{retcode}=$::RUNCMD_RC;
|
||||
# if($output =~ /stopped|not running/i){
|
||||
# $ret{retcode}=1;
|
||||
# }elsif($output =~ /running/i){
|
||||
# $ret{retcode}=0;
|
||||
# }
|
||||
}
|
||||
if($output)
|
||||
{
|
||||
$ret{retmsg}=$output;
|
||||
}
|
||||
|
||||
|
||||
if(defined $outputoption and $outputoption == 1 ){
|
||||
return \%ret;
|
||||
}elsif(exists $ret{retcode}){
|
||||
return $ret{retcode};
|
||||
}
|
||||
|
||||
return undef;
|
||||
|
||||
}
|
||||
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
|
||||
=head3 enableservice
|
||||
enable a service to start it on the system bootup
|
||||
Arguments:
|
||||
service name
|
||||
Returns:
|
||||
0 on success
|
||||
nonzero otherwise
|
||||
Globals:
|
||||
none
|
||||
Error:
|
||||
none
|
||||
Example:
|
||||
xCAT::Utils->enableservice("nfs");
|
||||
Comments:
|
||||
none
|
||||
=cut
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
sub enableservice{
|
||||
my $svcname=shift;
|
||||
if( $svcname =~ /xCAT::Utils/)
|
||||
{
|
||||
$svcname=shift;
|
||||
|
||||
}
|
||||
my $cmd="";
|
||||
my $svcunit=undef;
|
||||
my $svcd=undef;
|
||||
my $svcjob=undef;
|
||||
|
||||
$svcunit=servicemap($svcname,1);
|
||||
$svcjob=servicemap($svcname,2);
|
||||
$svcd=servicemap($svcname,0);
|
||||
if($svcunit)
|
||||
{
|
||||
$cmd="systemctl enable $svcunit";
|
||||
}
|
||||
elsif($svcjob)
|
||||
{
|
||||
$cmd="update-rc.d $svcjob defaults";
|
||||
|
||||
}
|
||||
elsif( $svcd )
|
||||
{
|
||||
my $CHKCONFIG = xCAT::Utils->fullpathbin("chkconfig");
|
||||
if($CHKCONFIG ne "chkconfig"){
|
||||
$cmd="$CHKCONFIG $svcd on";
|
||||
}else{
|
||||
$CHKCONFIG = xCAT::Utils->fullpathbin("update-rc.d");
|
||||
if($CHKCONFIG ne "update-rc.d"){
|
||||
$cmd="$CHKCONFIG $svcd defaults";
|
||||
}
|
||||
}
|
||||
}
|
||||
if( $cmd eq "" )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
xCAT::Utils->runcmd($cmd, -1);
|
||||
return $::RUNCMD_RC;
|
||||
}
|
||||
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
|
||||
=head3 disableservice
|
||||
disable a service to prevent it from starting on system bootup
|
||||
Arguments:
|
||||
service name
|
||||
Returns:
|
||||
0 on success
|
||||
nonzero otherwise
|
||||
Globals:
|
||||
none
|
||||
Error:
|
||||
none
|
||||
Example:
|
||||
xCAT::Utils->disableservice("nfs");
|
||||
Comments:
|
||||
none
|
||||
=cut
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
sub disableservice{
|
||||
my $svcname=shift;
|
||||
if( $svcname =~ /xCAT::Utils/)
|
||||
{
|
||||
$svcname=shift;
|
||||
|
||||
}
|
||||
my $cmd="";
|
||||
my $svcunit=undef;
|
||||
my $svcjob=undef;
|
||||
my $svcd=undef;
|
||||
|
||||
$svcunit=servicemap($svcname,1);
|
||||
$svcjob=servicemap($svcname,2);
|
||||
$svcd=servicemap($svcname,0);
|
||||
if($svcunit)
|
||||
{
|
||||
$cmd="systemctl disable $svcunit";
|
||||
}
|
||||
elsif($svcjob)
|
||||
{
|
||||
$cmd="update-rc.d -f $svcjob remove";
|
||||
|
||||
}
|
||||
elsif( $svcd )
|
||||
{
|
||||
my $CHKCONFIG = xCAT::Utils->fullpathbin("chkconfig");
|
||||
if($CHKCONFIG ne "chkconfig"){
|
||||
$cmd="$CHKCONFIG $svcd off";
|
||||
}else{
|
||||
$CHKCONFIG = xCAT::Utils->fullpathbin("update-rc.d");
|
||||
if($CHKCONFIG ne "update-rc.d"){
|
||||
$cmd="$CHKCONFIG -f $svcd remove";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# print "$cmd\n";
|
||||
if( $cmd eq "" )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
xCAT::Utils->runcmd($cmd, -1);
|
||||
return $::RUNCMD_RC;
|
||||
}
|
||||
1;
|
||||
|
||||
@@ -1,452 +0,0 @@
|
||||
#!/usr/bin/env perl
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
package xCAT::Zone;
|
||||
|
||||
BEGIN
|
||||
{
|
||||
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
|
||||
}
|
||||
|
||||
# if AIX - make sure we include perl 5.8.2 in INC path.
|
||||
# Needed to find perl dependencies shipped in deps tarball.
|
||||
if ($^O =~ /^aix/i) {
|
||||
unshift(@INC, qw(/usr/opt/perl5/lib/5.8.2/aix-thread-multi /usr/opt/perl5/lib/5.8.2 /usr/opt/perl5/lib/site_perl/5.8.2/aix-thread-multi /usr/opt/perl5/lib/site_perl/5.8.2));
|
||||
}
|
||||
|
||||
use lib "$::XCATROOT/lib/perl";
|
||||
# do not put a use or require for xCAT::Table here. Add to each new routine
|
||||
# needing it to avoid reprocessing of user tables ( ExtTab.pm) for each command call
|
||||
use POSIX qw(ceil);
|
||||
use File::Path;
|
||||
use Socket;
|
||||
use strict;
|
||||
use Symbol;
|
||||
use warnings "all";
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
|
||||
=head1 xCAT::Zone
|
||||
|
||||
=head2 Package Description
|
||||
|
||||
This program module file, is a set of Zone utilities used by xCAT *zone commands.
|
||||
|
||||
=cut
|
||||
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
|
||||
=head3 genSSHRootKeys
|
||||
Arguments:
|
||||
callback for error messages
|
||||
directory in which to put the ssh RSA keys
|
||||
zonename
|
||||
rsa private key to use for generation ( optional)
|
||||
Returns:
|
||||
Error: 1 - key generation failure.
|
||||
Example:
|
||||
$rc =xCAT::Zone->genSSHRootKeys($callback,$keydir,$rsakey);
|
||||
=cut
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
sub genSSHRootKeys
|
||||
{
|
||||
my ($class, $callback, $keydir,$zonename,$rsakey) = @_;
|
||||
|
||||
#
|
||||
# create /keydir if needed
|
||||
#
|
||||
if (!-d $keydir)
|
||||
{
|
||||
my $cmd = "/bin/mkdir -m 700 -p $keydir";
|
||||
my $output = xCAT::Utils->runcmd("$cmd", 0);
|
||||
if ($::RUNCMD_RC != 0)
|
||||
{
|
||||
my $rsp = {};
|
||||
$rsp->{error}->[0] =
|
||||
"Could not create $keydir directory";
|
||||
xCAT::MsgUtils->message("E", $rsp, $callback);
|
||||
return 1;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#need to gen a new rsa key for root for the zone
|
||||
my $pubfile = "$keydir/id_rsa.pub";
|
||||
my $pvtfile = "$keydir/id_rsa";
|
||||
|
||||
# if exists, remove the old files
|
||||
if (-r $pubfile)
|
||||
{
|
||||
|
||||
my $cmd = "/bin/rm $keydir/id_rsa*";
|
||||
my $output = xCAT::Utils->runcmd("$cmd", 0);
|
||||
if ($::RUNCMD_RC != 0)
|
||||
{
|
||||
my $rsp = {};
|
||||
$rsp->{error}->[0] = "Could not remove id_rsa files from $keydir directory.";
|
||||
xCAT::MsgUtils->message("E", $rsp, $callback);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
# gen new RSA keys
|
||||
my $cmd;
|
||||
my $output;
|
||||
# if private key was input use it
|
||||
if (defined ($rsakey)) {
|
||||
$cmd="/usr/bin/ssh-keygen -y -f $rsakey > $pubfile";
|
||||
$output = xCAT::Utils->runcmd("$cmd", 0);
|
||||
if ($::RUNCMD_RC != 0)
|
||||
{
|
||||
my $rsp = {};
|
||||
$rsp->{error}->[0] = "Could not generate $pubfile from $rsakey";
|
||||
xCAT::MsgUtils->message("E", $rsp, $callback);
|
||||
return 1;
|
||||
}
|
||||
# now copy the private key into the directory
|
||||
$cmd="cp $rsakey $keydir";
|
||||
$output = xCAT::Utils->runcmd("$cmd", 0);
|
||||
if ($::RUNCMD_RC != 0)
|
||||
{
|
||||
my $rsp = {};
|
||||
$rsp->{error}->[0] = "Could not run $cmd";
|
||||
xCAT::MsgUtils->message("E", $rsp, $callback);
|
||||
return 1;
|
||||
}
|
||||
} else { # generate all new keys
|
||||
$cmd = "/usr/bin/ssh-keygen -t rsa -q -b 2048 -N '' -f $pvtfile";
|
||||
$output = xCAT::Utils->runcmd("$cmd", 0);
|
||||
if ($::RUNCMD_RC != 0)
|
||||
{
|
||||
my $rsp = {};
|
||||
$rsp->{error}->[0] = "Could not generate $pubfile";
|
||||
xCAT::MsgUtils->message("E", $rsp, $callback);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
#make sure permissions are correct
|
||||
$cmd = "chmod 644 $pubfile;chown root $pubfile";
|
||||
$output = xCAT::Utils->runcmd("$cmd", 0);
|
||||
if ($::RUNCMD_RC != 0)
|
||||
{
|
||||
my $rsp = {};
|
||||
$rsp->{error}->[0] = "Could set permission and owner on $pubfile";
|
||||
xCAT::MsgUtils->message("E", $rsp, $callback);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
#--------------------------------------------------------------------------------
|
||||
|
||||
=head3 getdefaultzone
|
||||
Arguments:
|
||||
None
|
||||
Returns:
|
||||
Name of the current default zone from the zone table
|
||||
Example:
|
||||
my $defaultzone =xCAT::Zone->getdefaultzone($callback);
|
||||
=cut
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
sub getdefaultzone
|
||||
{
|
||||
my ($class, $callback) = @_;
|
||||
my $defaultzone;
|
||||
# read all the zone table and find the defaultzone, if it exists
|
||||
my $tab = xCAT::Table->new("zone");
|
||||
if ($tab){
|
||||
my @zones = $tab->getAllAttribs('zonename','defaultzone');
|
||||
foreach my $zone (@zones) {
|
||||
# Look for the defaultzone=yes/1 entry
|
||||
if ((defined($zone->{defaultzone})) &&
|
||||
(($zone->{defaultzone} =~ /^yes$/i )
|
||||
|| ($zone->{defaultzone} eq "1"))) {
|
||||
$defaultzone = $zone->{zonename};
|
||||
}
|
||||
$tab->close();
|
||||
}
|
||||
} else {
|
||||
my $rsp = {};
|
||||
$rsp->{error}->[0] =
|
||||
"Error reading the zone table. ";
|
||||
xCAT::MsgUtils->message("E", $rsp, $callback);
|
||||
|
||||
}
|
||||
return $defaultzone;
|
||||
}
|
||||
#--------------------------------------------------------------------------------
|
||||
|
||||
=head3 iszonedefined
|
||||
Arguments:
|
||||
zonename
|
||||
Returns:
|
||||
1 if the zone is already in the zone table.
|
||||
Example:
|
||||
xCAT::Zone->iszonedefined($zonename);
|
||||
=cut
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
sub iszonedefined
|
||||
{
|
||||
my ($class,$zonename) = @_;
|
||||
# checks the zone table to see if input zonename already in the table
|
||||
my $tab = xCAT::Table->new("zone");
|
||||
$tab->close();
|
||||
my $zonehash = $tab->getAttribs({zonename => $zonename},'sshkeydir');
|
||||
if ( keys %$zonehash) {
|
||||
return 1;
|
||||
}else{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#--------------------------------------------------------------------------------
|
||||
|
||||
=head3 getzonekeydir
|
||||
Arguments:
|
||||
zonename
|
||||
Returns:
|
||||
path to the root ssh keys for the zone /etc/xcat/sshkeys/<zonename>/.ssh
|
||||
1 - zone not defined
|
||||
Example:
|
||||
xCAT::Zone->getzonekeydir($zonename);
|
||||
=cut
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
sub getzonekeydir
|
||||
{
|
||||
my ($class,$zonename) = @_;
|
||||
my $tab = xCAT::Table->new("zone");
|
||||
$tab->close();
|
||||
my $zonehash = $tab->getAttribs({zonename => $zonename},'sshkeydir');
|
||||
if ( keys %$zonehash) {
|
||||
my $zonesshkeydir=$zonehash->{sshkeydir};
|
||||
return $zonesshkeydir;
|
||||
}else{
|
||||
return 1; # this is a bad error zone not defined
|
||||
}
|
||||
}
|
||||
#--------------------------------------------------------------------------------
|
||||
|
||||
=head3 getmyzonename
|
||||
Arguments:
|
||||
$node -one nodename
|
||||
Returns:
|
||||
$zonename
|
||||
Example:
|
||||
my $zonename=xCAT::Zone->getmyzonename($node);
|
||||
=cut
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
sub getmyzonename
|
||||
{
|
||||
my ($class,$node,$callback) = @_;
|
||||
my @node;
|
||||
push @node,$node;
|
||||
my $zonename;
|
||||
my $nodelisttab = xCAT::Table->new("nodelist");
|
||||
my $nodehash = $nodelisttab->getNodesAttribs(\@node, ['zonename']);
|
||||
$nodelisttab->close();
|
||||
if ( defined ($nodehash->{$node}->[0]->{zonename})) { # it was defined in the nodelist table
|
||||
$zonename=$nodehash->{$node}->[0]->{zonename};
|
||||
} else { # get the default zone
|
||||
$zonename =xCAT::Zone->getdefaultzone($callback);
|
||||
}
|
||||
return $zonename;
|
||||
}
|
||||
#--------------------------------------------------------------------------------
|
||||
|
||||
=head3 enableSSHbetweennodes
|
||||
Arguments:
|
||||
zonename
|
||||
Returns:
|
||||
1 if the sshbetweennodes attribute is yes/1 or undefined
|
||||
0 if the sshbetweennodes attribute is no/0
|
||||
Example:
|
||||
xCAT::Zone->enableSSHbetweennodes($zonename);
|
||||
=cut
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
sub enableSSHbetweennodes
|
||||
{
|
||||
my ($class,$node,$callback) = @_;
|
||||
# finds the zone of the node
|
||||
my $enablessh = 1; # default
|
||||
my $zonename=xCAT::Zone->getmyzonename($node);
|
||||
# reads the zone table
|
||||
my $tab = xCAT::Table->new("zone");
|
||||
$tab->close();
|
||||
# read both keys, want to know zone is in the zone table. If sshkeydir is not there
|
||||
# it is either missing or invalid anyway
|
||||
my $zonehash = $tab->getAttribs({zonename => $zonename},'sshbetweennodes','sshkeydir');
|
||||
if (! ( keys %$zonehash)) {
|
||||
my $rsp = {};
|
||||
$rsp->{error}->[0] =
|
||||
"$node has a zonename: $zonename that is not define in the zone table. Remove the zonename from the node, or create the zone using mkzone. The generated mypostscript may not reflect the correct setting for ENABLESSHBETWEENNODES";
|
||||
xCAT::MsgUtils->message("E", $rsp, $callback);
|
||||
return $enablessh;
|
||||
}
|
||||
my $sshbetweennodes=$zonehash->{sshbetweennodes};
|
||||
if (defined ($sshbetweennodes)) {
|
||||
if (($sshbetweennodes =~ /^no$/i) || ($sshbetweennodes eq "0")) {
|
||||
$enablessh = 0;
|
||||
} else {
|
||||
$enablessh = 1;
|
||||
}
|
||||
} else { # not defined default yes
|
||||
$enablessh = 1 ; # default
|
||||
}
|
||||
return $enablessh;
|
||||
}
|
||||
#--------------------------------------------------------------------------------
|
||||
|
||||
=head3 usingzones
|
||||
Arguments:
|
||||
none
|
||||
Returns:
|
||||
1 if the zone table is not empty
|
||||
0 if empty
|
||||
Example:
|
||||
xCAT::Zone->usingzones;
|
||||
=cut
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
sub usingzones
|
||||
{
|
||||
my ($class) = @_;
|
||||
# reads the zonetable
|
||||
my $tab = xCAT::Table->new("zone");
|
||||
my @zone = $tab->getAllAttribs('zonename');
|
||||
$tab->close();
|
||||
if (@zone) {
|
||||
return 1;
|
||||
}else{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#--------------------------------------------------------------------------------
|
||||
|
||||
=head3 getzoneinfo
|
||||
Arguments:
|
||||
callback
|
||||
An array of nodes
|
||||
Returns:
|
||||
Hash array by zonename point to the nodes in that zonename and sshkeydir
|
||||
<zonename1> -> {nodelist} -> array of nodes in the zone
|
||||
-> {sshkeydir} -> directory containing ssh RSA keys
|
||||
-> {defaultzone} -> is it the default zone
|
||||
Example:
|
||||
my %zonehash =xCAT::Zone->getzoneinfo($callback,@nodearray);
|
||||
Rules:
|
||||
If the nodes nodelist.zonename attribute is a zonename, it is assigned to that zone
|
||||
If the nodes nodelist.zonename attribute is undefined:
|
||||
If there is a defaultzone in the zone table, the node is assigned to that zone
|
||||
If there is no defaultzone in the zone table, the node is assigned to the ~.ssh keydir
|
||||
$::GETZONEINFO_RC
|
||||
0 = good return
|
||||
1 = error occured
|
||||
=cut
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
sub getzoneinfo
|
||||
{
|
||||
my ($class, $callback,$nodes) = @_;
|
||||
$::GETZONEINFO_RC=0;
|
||||
my $zonehash;
|
||||
my $defaultzone;
|
||||
# read all the zone table
|
||||
my $zonetab = xCAT::Table->new("zone");
|
||||
my @zones;
|
||||
if ($zonetab){
|
||||
@zones = $zonetab->getAllAttribs('zonename','sshkeydir','sshbetweennodes','defaultzone');
|
||||
$zonetab->close();
|
||||
if (@zones) {
|
||||
foreach my $zone (@zones) {
|
||||
my $zonename=$zone->{zonename};
|
||||
$zonehash->{$zonename}->{sshkeydir}= $zone->{sshkeydir};
|
||||
$zonehash->{$zonename}->{defaultzone}= $zone->{defaultzone};
|
||||
$zonehash->{$zonename}->{sshbetweennodes}= $zone->{sshbetweennodes};
|
||||
# find the defaultzone
|
||||
if ((defined($zone->{defaultzone})) &&
|
||||
(($zone->{defaultzone} =~ /^yes$/i )
|
||||
|| ($zone->{defaultzone} eq "1"))) {
|
||||
$defaultzone = $zone->{zonename};
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
my $rsp = {};
|
||||
$rsp->{error}->[0] =
|
||||
"Error reading the zone table. ";
|
||||
xCAT::MsgUtils->message("E", $rsp, $callback);
|
||||
$::GETZONEINFO_RC =1;
|
||||
return;
|
||||
|
||||
}
|
||||
my $nodelisttab = xCAT::Table->new("nodelist");
|
||||
my $nodehash = $nodelisttab->getNodesAttribs(\@$nodes, ['zonename']);
|
||||
# for each of the nodes, look up it's zone name and assign to the zonehash
|
||||
# If the nodes nodelist.zonename attribute is a zonename, it is assigned to that zone
|
||||
# If the nodes nodelist.zonename attribute is undefined:
|
||||
# If there is a defaultzone in the zone table, the node is assigned to that zone
|
||||
# If there is no defaultzone error out
|
||||
|
||||
|
||||
foreach my $node (@$nodes) {
|
||||
my $zonename;
|
||||
$zonename=$nodehash->{$node}->[0]->{zonename};
|
||||
if (defined($zonename)) { # zonename explicitly defined in nodelist.zonename
|
||||
# check to see if defined in the zone table
|
||||
unless ( xCAT::Zone->iszonedefined($zonename)) {
|
||||
my $rsp = {};
|
||||
$rsp->{error}->[0] =
|
||||
"$node has a zonename: $zonename that is not define in the zone table. Remove the zonename from the node, or create the zone using mkzone.";
|
||||
xCAT::MsgUtils->message("E", $rsp, $callback);
|
||||
$::GETZONEINFO_RC =1;
|
||||
return;
|
||||
}
|
||||
push @{$zonehash->{$zonename}->{nodes}},$node;
|
||||
} else { # no explict zonename
|
||||
if (defined ($defaultzone)) { # there is a default zone in the zone table, use it
|
||||
push @{$zonehash->{$defaultzone}->{nodes}},$node;
|
||||
} else { # if no default, this is an error
|
||||
my $rsp = {};
|
||||
$rsp->{error}->[0] =
|
||||
"There is no default zone defined in the zone table. There must be exactly one default zone. ";
|
||||
xCAT::MsgUtils->message("E", $rsp, $callback);
|
||||
$::GETZONEINFO_RC =1;
|
||||
return;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return $zonehash;
|
||||
}
|
||||
#--------------------------------------------------------------------------------
|
||||
|
||||
=head3 getnodesinzone
|
||||
Arguments:
|
||||
callback
|
||||
zonename
|
||||
Returns:
|
||||
Array of nodes
|
||||
Example:
|
||||
my @nodes =xCAT::Zone->getnodesinzone($callback,$zonename);
|
||||
=cut
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
sub getnodesinzone
|
||||
{
|
||||
my ($class, $callback,$zonename) = @_;
|
||||
my @nodes;
|
||||
my $nodelisttab = xCAT::Table->new("nodelist");
|
||||
my @nodelist=$nodelisttab->getAllAttribs('node','zonename');
|
||||
# build the array of nodes in this zone
|
||||
foreach my $nodename (@nodelist) {
|
||||
if ((defined($nodename->{'zonename'})) && ($nodename->{'zonename'} eq $zonename)) {
|
||||
push @nodes,$nodename->{'node'};
|
||||
}
|
||||
}
|
||||
return @nodes;
|
||||
}
|
||||
1;
|
||||
@@ -14,11 +14,9 @@ require Exporter;
|
||||
|
||||
%distnames = (
|
||||
"1310229985.226287" => "centos6",
|
||||
"1323560292.885204" => "centos6.2",
|
||||
"1341569670.539525" => "centos6.3",#x86
|
||||
"1362445555.957609" => "centos6.4",#x86_64
|
||||
"1385726732.061157" => "centos6.5",#x86_64
|
||||
"1404489053.504589" => "centos7.0",
|
||||
"1323560292.885204" => "centos6.2",
|
||||
"1341569670.539525" => "centos6.3",#x86
|
||||
"1362445555.957609" => "centos6.4",#x86_64
|
||||
"1176234647.982657" => "centos5",
|
||||
"1156364963.862322" => "centos4.4",
|
||||
"1178480581.024704" => "centos4.5",
|
||||
@@ -30,7 +28,6 @@ require Exporter;
|
||||
"1272326751.405938" => "centos5.5",
|
||||
"1330913492.861127" => "centos5.8",#x86_64
|
||||
"1357930415.252042" => "centos5.9",#x86_64
|
||||
"1381776971.473332" => "centos5.10",#x86_64
|
||||
"1195488871.805863" => "centos4.6",
|
||||
"1195487524.127458" => "centos4.6",
|
||||
"1301444731.448392" => "centos5.6",
|
||||
@@ -52,8 +49,6 @@ require Exporter;
|
||||
"1328205744.315196" => "rhels5.8", #x86_64
|
||||
"1354216429.587870" => "rhels5.9", #x86_64
|
||||
"1354214009.518521" => "rhels5.9", #ppc64
|
||||
"1378846702.129847" => "rhels5.10", #x86_64
|
||||
"1378845049.643372" => "rhels5.10", #ppc64
|
||||
"1285193176.460470" => "rhels6", #x86_64
|
||||
"1285192093.430930" => "rhels6", #ppc64
|
||||
"1305068199.328169" => "rhels6.1", #x86_64
|
||||
@@ -65,15 +60,11 @@ require Exporter;
|
||||
"1339638991.532890" => "rhels6.3", #i386
|
||||
"1359576752.435900" => "rhels6.4", #x86_64
|
||||
"1359576196.686790" => "rhels6.4", #ppc64
|
||||
"1384196515.415715" => "rhels6.5", #x86_64
|
||||
"1384198011.520581" => "rhels6.5", #ppc64
|
||||
"1285193176.593806" => "rhelhpc6", #x86_64
|
||||
"1305067719.718814" => "rhelhpc6.1",#x86_64
|
||||
"1321545261.599847" => "rhelhpc6.2",#x86_64
|
||||
"1339640148.070971" => "rhelhpc6.3",#x86_64
|
||||
"1359576195.413831" => "rhelhpc6.4",#x86_64, RHEL ComputeNode
|
||||
"1384196516.465862" => "rhelhpc6.5",#x86_64, RHEL ComputeNode
|
||||
"1399449226.140088" => "rhelhpc7.0",#x86_64, RHEL ComputeNode
|
||||
"1194015916.783841" => "fedora8",
|
||||
"1194015385.299901" => "fedora8",
|
||||
"1210112435.291709" => "fedora9",
|
||||
@@ -87,16 +78,13 @@ require Exporter;
|
||||
"1305315870.828212" => "fedora15", #x86_64 DVD ISO
|
||||
"1372355769.065812" => "fedora19", #x86_64 DVD ISO
|
||||
"1372402928.663653" => "fedora19", #ppc64 DVD ISO
|
||||
"1386856788.124593" => "fedora20", #x86_64 DVD ISO
|
||||
|
||||
"1194512200.047708" => "rhas4.6",
|
||||
"1194512327.501046" => "rhas4.6",
|
||||
"1241464993.830723" => "rhas4.8", #x86-64
|
||||
|
||||
"1273608367.051780" => "SL5.5", #x86_64 DVD ISO
|
||||
"1299104542.844706" => "SL6", #x86_64 DVD ISO
|
||||
"1390839789.062069" => "SL6.5", #x86_64 DVD ISO Install
|
||||
|
||||
"1394111947.452332" => "pkvm2.1", # ppc64, PowerKVM
|
||||
"1273608367.051780" => "SL5.5", #x86_64 DVD ISO
|
||||
"1299104542.844706" => "SL6", #x86_64 DVD ISO
|
||||
);
|
||||
my %numdiscs = (
|
||||
"1156364963.862322" => 4,
|
||||
|
||||
+3755
-917
File diff suppressed because it is too large
Load Diff
@@ -611,25 +611,39 @@ sub punch2Reader {
|
||||
|
||||
# Punch to reader
|
||||
# VMUR located in different directories on RHEL and SLES
|
||||
my $out;
|
||||
my $vmur;
|
||||
if ( $os =~ m/sles10/i ) {
|
||||
$out = `ssh -o ConnectTimeout=5 $user\@$hcp "$sudo /sbin/vmur punch $options -u $userId -r $srcFile -N $tgtFile"`;
|
||||
} elsif ( $os =~ m/sles11/i ) {
|
||||
$out = `ssh -o ConnectTimeout=5 $user\@$hcp "$sudo /usr/sbin/vmur punch $options -u $userId -r $srcFile -N $tgtFile"`;
|
||||
} elsif ( $os =~ m/rhel/i ) {
|
||||
$out = `ssh -o ConnectTimeout=5 $user\@$hcp "$sudo /usr/sbin/vmur punch $options -u $userId -r $srcFile -N $tgtFile"`;
|
||||
$vmur = "/sbin/vmur";
|
||||
} else {
|
||||
$out = `ssh -o ConnectTimeout=5 $user\@$hcp "$sudo /usr/sbin/vmur punch $options -u $userId -r $srcFile -N $tgtFile"`;
|
||||
$vmur = "/usr/sbin/vmur";
|
||||
}
|
||||
my $out;
|
||||
my $done = 0;
|
||||
|
||||
until ( $done ) {
|
||||
$out = `ssh -o ConnectTimeout=5 $user\@$hcp "$sudo $vmur punch $options -u $userId -r $srcFile -N $tgtFile" 2>&1`;
|
||||
my $rc = $? >> 8;
|
||||
if ( $rc == 255 ) {
|
||||
$out = "(Error) Unable to communicate with the zHCP system: $hcp";
|
||||
$done = 1;
|
||||
} elsif ( $out =~ m/A concurrent instance of vmur is already active/i ) {
|
||||
# Recoverable error: retry the command after a delay
|
||||
xCAT::zvmUtils->printSyslog( "punch2Reader() Punch in use on $hcp, retrying in 15 seconds" );
|
||||
sleep( 15 );
|
||||
} else {
|
||||
# Punch appears successful -- Look for the completion string
|
||||
my $searchStr = "created and transferred";
|
||||
if ( !( $out =~ m/$searchStr/i ) ) {
|
||||
chomp( $out );
|
||||
$out = "Failed, punch info: '$out'\n";
|
||||
xCAT::zvmUtils->printSyslog( "punch2Reader() Failed punching $srcFile to $userId from $hcp, info: '$out'" );
|
||||
} else {
|
||||
$out = "Done\n";
|
||||
}
|
||||
$done = 1;
|
||||
}
|
||||
}
|
||||
|
||||
# If punch is successful -- Look for this string
|
||||
my $searchStr = "created and transferred";
|
||||
if ( !( $out =~ m/$searchStr/i ) ) {
|
||||
$out = "Failed\n";
|
||||
} else {
|
||||
$out = "Done\n";
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
|
||||
+214
-132
@@ -289,7 +289,7 @@ sub printLn {
|
||||
# Print string
|
||||
my $rsp;
|
||||
my $type = "I";
|
||||
if ($str =~ m/error/i) { # Set to print error if the string contains error
|
||||
if ($str =~ m/(\(error\)|\sfailed)/i) { # Set to print error if the string contains error
|
||||
$type = "E";
|
||||
}
|
||||
|
||||
@@ -1246,7 +1246,7 @@ sub getArch {
|
||||
}
|
||||
|
||||
# Get host using VMCP
|
||||
my $arch = `ssh $user\@$node "$sudo uname -p"`;
|
||||
my $arch = `ssh $user\@$node "$sudo uname -m"`;
|
||||
|
||||
return ( xCAT::zvmUtils->trimStr($arch) );
|
||||
}
|
||||
@@ -2308,19 +2308,20 @@ sub getUsedFcpDevices {
|
||||
Arguments : Sudoer user name
|
||||
Sudo keyword
|
||||
zHCP hostname
|
||||
Install root directory
|
||||
Local directory to remotely mount
|
||||
Mount access ('ro' for read only, 'rw' for read write)
|
||||
Directory as known to zHCP (out)
|
||||
Returns : 0 - Mounted, or zHCP and MN are on the same system
|
||||
1 - Mount failed
|
||||
Example : establishMount( $callback, $::SUDOER, $::SUDO, $hcp, "$installRoot/$provMethod", "ro", \$remoteDeployDir );
|
||||
Example : establishMount( $callback, $::SUDOER, $::SUDO, $hcp, $installRoot, $provMethod, "ro", \$remoteDeployDir );
|
||||
|
||||
=cut
|
||||
|
||||
#-------------------------------------------------------
|
||||
sub establishMount {
|
||||
# Get inputs
|
||||
my ($class, $callback, $sudoer, $sudo, $hcp, $localDir, $access, $mountedPt) = @_;
|
||||
my ($class, $callback, $sudoer, $sudo, $hcp, $installRoot, $localDir, $access, $mountedPt) = @_;
|
||||
my $out;
|
||||
|
||||
# If the target system is not on this system then establish the NFS mount point.
|
||||
@@ -2338,7 +2339,7 @@ sub establishMount {
|
||||
|
||||
if ($masterIp eq $hcpIP) {
|
||||
# xCAT MN and zHCP are on the same box and will use the same directory without the need for an NFS mount.
|
||||
$$mountedPt = $localDir;
|
||||
$$mountedPt = "$installRoot/$localDir";
|
||||
} else {
|
||||
# Determine the hostname for this management node
|
||||
my $masterHostname = Sys::Hostname::hostname();
|
||||
@@ -2347,15 +2348,23 @@ sub establishMount {
|
||||
$masterHostname = $masterIp;
|
||||
}
|
||||
|
||||
$$mountedPt = "/mnt/$masterHostname$installRoot/$localDir";
|
||||
|
||||
# If the mount point already exists then return because we are done.
|
||||
my $rc = `ssh $sudoer\@$hcp "$sudo mount | grep $$mountedPt > /dev/null; echo \\\$?"`;
|
||||
if ($rc == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
xCAT::zvmUtils->printSyslog( "establishMount() Preparing the NFS mount point on zHCP ($hcpIP) to xCAT MN $masterHostname($masterIp) for $localDir" );
|
||||
|
||||
# Prepare the staging mount point on zHCP, if they need to be established
|
||||
$$mountedPt = "/mnt/$masterHostname$localDir";
|
||||
my $rc = `ssh $sudoer\@$hcp "$sudo mkdir -p $$mountedPt && mount -t nfs -o $access $masterIp:$localDir $$mountedPt; echo \\\$?"`;
|
||||
$rc = `ssh $sudoer\@$hcp "$sudo mkdir -p $$mountedPt && mount -t nfs -o $access $masterIp:/$localDir $$mountedPt; echo \\\$?"`;
|
||||
|
||||
# Return code = 0 (mount succeeded) or 32 (mount already exists)
|
||||
if ($rc != '0' && $rc != '32') {
|
||||
# Return code = 0 (mount succeeded)
|
||||
if ($rc != '0') {
|
||||
xCAT::zvmUtils->printLn( $callback, "$hcp: (Error) Unable to establish zHCP mount point: $$mountedPt" );
|
||||
xCAT::zvmUtils->printSyslog( "establishMount() Unable to establish zHCP mount point: $$mountedPt, rc: $rc" );
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -2367,9 +2376,12 @@ sub establishMount {
|
||||
|
||||
=head3 getFreeRepoSpace
|
||||
|
||||
Description : Get the free space of image repository under /install
|
||||
Description : Get the free space of image repository under /install.
|
||||
Arguments : Node
|
||||
Returns : The available space for /install
|
||||
Returns : The available space for /install (e.g. "2.1G ").
|
||||
The value is returned as a perl string (e.g. "0 ") to
|
||||
avoid perl returning null instead of "0" in the case
|
||||
of no space available.
|
||||
Example : my $free = getFreeRepoSpace($callback, $node);
|
||||
|
||||
=cut
|
||||
@@ -2393,9 +2405,12 @@ sub getFreeRepoSpace {
|
||||
if ($master eq $ip) {
|
||||
# If the master IP and node IP match, then it is the management node
|
||||
my $out = `$sudo /bin/df -h /install | sed 1d`;
|
||||
# causing problems on other platforms $out =~ s/\h+/ /g;$out =~ s/\h+/ /g;
|
||||
$out =~ s/\h+/ /g;
|
||||
my @results = split(' ', $out);
|
||||
return ($results[3]);
|
||||
if ( $results[3] eq "0" ) {
|
||||
$results[3] = "0M";
|
||||
}
|
||||
return $results[3];
|
||||
}
|
||||
|
||||
return;
|
||||
@@ -2475,12 +2490,12 @@ sub findAndUpdatezFcpPool {
|
||||
return \%results;
|
||||
}
|
||||
|
||||
# Check WWPN and LUN syntax
|
||||
if ( $wwpn && ($wwpn =~ /[^0-9a-f;"]/i) ) {
|
||||
xCAT::zvmUtils->printLn( $callback, "$header: (Error) Invalid world wide portname $wwpn." );
|
||||
# Owner must be specified if status is used
|
||||
if ($status =~ m/used/i && !$owner) {
|
||||
xCAT::zvmUtils->printLn( $callback, "$header: (Error) Owner must be specified if status is used." );
|
||||
return \%results;
|
||||
} if ( $lun && ($lun =~ /[^0-9a-f]/i) ) {
|
||||
xCAT::zvmUtils->printLn( $callback, "$header: (Error) Invalid logical unit number $lun." );
|
||||
} elsif ($status =~ m/free/i && $owner) {
|
||||
xCAT::zvmUtils->printLn( $callback, "$header: (Error) Owner must not be specified if status is free." );
|
||||
return \%results;
|
||||
}
|
||||
|
||||
@@ -2509,6 +2524,15 @@ sub findAndUpdatezFcpPool {
|
||||
# Make sure WWPN and LUN do not have 0x prefix
|
||||
$wwpn = xCAT::zvmUtils->replaceStr($wwpn, "0x", "");
|
||||
$lun = xCAT::zvmUtils->replaceStr($lun, "0x", "");
|
||||
|
||||
# Check WWPN and LUN syntax
|
||||
if ( $wwpn && ($wwpn =~ /[^0-9a-f;"]/i) ) {
|
||||
xCAT::zvmUtils->printLn( $callback, "$header: (Error) Invalid world wide portname $wwpn." );
|
||||
return \%results;
|
||||
} if ( $lun && ($lun =~ /[^0-9a-f]/i) ) {
|
||||
xCAT::zvmUtils->printLn( $callback, "$header: (Error) Invalid logical unit number $lun." );
|
||||
return \%results;
|
||||
}
|
||||
}
|
||||
|
||||
# Find disk pool (create one if non-existent)
|
||||
@@ -2569,15 +2593,19 @@ sub findAndUpdatezFcpPool {
|
||||
}
|
||||
|
||||
# Do not continue if no devices can be found
|
||||
if (!$wwpn && !$lun) {
|
||||
if (!$wwpn || !$lun) {
|
||||
xCAT::zvmUtils->printLn($callback, "$header: (Error) A suitable device of $size" . "M or larger could not be found");
|
||||
return \%results;
|
||||
}
|
||||
} else {
|
||||
# Find given WWPN and LUN. Do not continue if device is used
|
||||
# Find given WWPN and LUN. Do not continue if device is used
|
||||
my $select = `ssh $user\@$hcp "$sudo cat $zfcpDir/$pool.conf" | grep -i "$wwpn,$lun"`;
|
||||
chomp($select);
|
||||
|
||||
if (!$select) {
|
||||
xCAT::zvmUtils->printLn($callback, "$header: (Error) zFCP device 0x$wwpn/0x$lun could not be found in zFCP pool $pool");
|
||||
return \%results;
|
||||
}
|
||||
|
||||
@info = split(',', $select);
|
||||
|
||||
if ($size) {
|
||||
@@ -2585,13 +2613,11 @@ sub findAndUpdatezFcpPool {
|
||||
# Convert to MegaBytes
|
||||
$info[3] =~ s/\D//g;
|
||||
$info[3] = int($info[3]) * 1024
|
||||
} elsif ($info[3] =~ m/M/i) {
|
||||
} else {
|
||||
# Do nothing
|
||||
$info[3] =~ s/\D//g;
|
||||
} else {
|
||||
next;
|
||||
}
|
||||
|
||||
|
||||
# Do not continue if specified device does not have enough capacity
|
||||
if ($info[3] < $size) {
|
||||
xCAT::zvmUtils->printLn($callback, "$header: (Error) FCP device $wwpn/$lun is not large enough");
|
||||
@@ -2602,7 +2628,7 @@ sub findAndUpdatezFcpPool {
|
||||
# Find range of the specified disk
|
||||
$range = $info[4];
|
||||
}
|
||||
|
||||
|
||||
# If there are multiple paths, take the 1st one
|
||||
# Handle multi-pathing in postscript because autoyast/kickstart does not support it.
|
||||
my $origWwpn = $wwpn;
|
||||
@@ -2612,117 +2638,23 @@ sub findAndUpdatezFcpPool {
|
||||
}
|
||||
|
||||
xCAT::zvmUtils->printLn($callback, "$header: Found FCP device 0x$wwpn/0x$lun");
|
||||
|
||||
# Find a free FCP device based on the given range
|
||||
if ($fcpDevice =~ m/^auto/i) {
|
||||
my @ranges;
|
||||
my $min;
|
||||
my $max;
|
||||
my $found = 0;
|
||||
|
||||
if ($range =~ m/;/i) {
|
||||
@ranges = split(';', $range);
|
||||
} else {
|
||||
push(@ranges, $range);
|
||||
}
|
||||
|
||||
if (!$found) {
|
||||
# If the node has an eligible FCP device, use it
|
||||
my @deviceList = xCAT::zvmUtils->getDedicates($callback, $user, $owner);
|
||||
foreach (@deviceList) {
|
||||
# Check if this devide is eligible (among the range specified for disk $lun)
|
||||
@info = split(' ', $_);
|
||||
my $candidate = $info[2];
|
||||
foreach (@ranges) {
|
||||
($min, $max) = split('-', $_);
|
||||
if (hex($candidate) >= hex($min) && hex($candidate) <= hex($max)) {
|
||||
$found = 1;
|
||||
$fcpDevice = uc($candidate);
|
||||
|
||||
last;
|
||||
}
|
||||
}
|
||||
|
||||
if ($found) {
|
||||
xCAT::zvmUtils->printLn($callback, "$header: Found eligible FCP channel $fcpDevice");
|
||||
last;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$found) {
|
||||
# If the node has no eligible FCP device, find a free one for it.
|
||||
my %usedDevices = xCAT::zvmUtils->getUsedFcpDevices($user, $hcp);
|
||||
|
||||
my $hcpUserId = xCAT::zvmCPUtils->getUserId($user, $hcp);
|
||||
$hcpUserId =~ tr/a-z/A-Z/;
|
||||
|
||||
# Find a free FCP channel
|
||||
$out = `ssh $user\@$hcp "$sudo $dir/smcli System_WWPN_Query -T $hcpUserId" | egrep -i "FCP device number|Status"`;
|
||||
my @devices = split( "\n", $out );
|
||||
for (my $i = 0; $i < @devices; $i++) {
|
||||
# Extract the device number and status
|
||||
$fcpDevice = $devices[$i];
|
||||
$fcpDevice =~ s/^FCP device number:(.*)/$1/;
|
||||
$fcpDevice =~ s/^\s+//;
|
||||
$fcpDevice =~ s/\s+$//;
|
||||
|
||||
$i++;
|
||||
my $fcpStatus = $devices[$i];
|
||||
$fcpStatus =~ s/^Status:(.*)/$1/;
|
||||
$fcpStatus =~ s/^\s+//;
|
||||
$fcpStatus =~ s/\s+$//;
|
||||
|
||||
# Only look at free FCP devices
|
||||
if ($fcpStatus =~ m/free/i) {
|
||||
# If the device number is within the specified range, exit out of loop
|
||||
# Range: 3B00-3C00;4B00-4C00;5E12-5E12
|
||||
foreach (@ranges) {
|
||||
($min, $max) = split('-', $_);
|
||||
if (hex($fcpDevice) >= hex($min) && hex($fcpDevice) <= hex($max)) {
|
||||
$fcpDevice = uc($fcpDevice);
|
||||
|
||||
# Used found FCP channel if not in use or allocated
|
||||
if (!$usedDevices{$fcpDevice}) {
|
||||
$found = 1;
|
||||
last;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Break out of loop if FCP channel is found
|
||||
if ($found) {
|
||||
xCAT::zvmUtils->printLn($callback, "$header: Found FCP channel within acceptable range $fcpDevice");
|
||||
last;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Do not continue if no FCP channel is found
|
||||
if (!$found) {
|
||||
xCAT::zvmUtils->printLn($callback, "$header: (Error) A suitable FCP channel could not be found");
|
||||
|
||||
if ( ($status =~ m/used/i) && ($fcpDevice =~ /^auto/i) ) {
|
||||
# select an eligible FCP device
|
||||
$fcpDevice = xCAT::zvmUtils->selectFcpDevice($callback, $header, $user, $hcp, $fcpDevice, $range, $owner);
|
||||
if (!$fcpDevice) {
|
||||
return \%results;
|
||||
}
|
||||
}
|
||||
|
||||
# If there are multiple devices (multipathing), take the 1st one
|
||||
if ($fcpDevice) {
|
||||
if ($fcpDevice =~ m/;/i) {
|
||||
@info = split(';', $fcpDevice);
|
||||
$fcpDevice = xCAT::zvmUtils->trimStr($info[0]);
|
||||
}
|
||||
|
||||
# Make sure channel has a length of 4
|
||||
while (length($fcpDevice) < 4) {
|
||||
$fcpDevice = "0" . $fcpDevice;
|
||||
}
|
||||
} elsif ($status =~ m/free/i) {
|
||||
# Owner and FCP channel make no sense when status is free
|
||||
$fcpDevice = "";
|
||||
$owner = "";
|
||||
}
|
||||
|
||||
# Mark WWPN and LUN as used, free, or reserved and set the owner/channel appropriately
|
||||
# This config file keeps track of the owner of each device, which is useful in nodeset
|
||||
$size = $size . "M";
|
||||
my $select = `ssh $user\@$hcp "$sudo cat $zfcpDir/$pool.conf" | grep -i "$lun" | grep -i "$wwpn"`;
|
||||
my $select = `ssh $user\@$hcp "$sudo cat $zfcpDir/$pool.conf" | grep -i "$lun"`;
|
||||
chomp($select);
|
||||
if ($select) {
|
||||
@info = split(',', $select);
|
||||
@@ -2759,6 +2691,156 @@ sub findAndUpdatezFcpPool {
|
||||
|
||||
#-------------------------------------------------------
|
||||
|
||||
=head3 selectFcpDevice
|
||||
|
||||
Description : Select an eligible FCP device for attaching a zFCP device to a node
|
||||
Arguments : Message header
|
||||
User (root or non-root)
|
||||
zHCP
|
||||
candidate FCP devices or auto
|
||||
FCP device range
|
||||
zFCP device owner
|
||||
Returns : selected FCP device or empty if no one is selected
|
||||
Example : my $fcpDevice = xCAT::zvmUtils->selectFcpDevice($callback, $header, $user, $hcp, $fcpDevice, $range, $owner);
|
||||
|
||||
=cut
|
||||
|
||||
#-------------------------------------------------------
|
||||
sub selectFcpDevice {
|
||||
# Get inputs
|
||||
my ($class, $callback, $header, $user, $hcp, $fcpDevice, $range, $owner) = @_;
|
||||
|
||||
# Determine if sudo is used
|
||||
my $sudo = "sudo";
|
||||
if ($user eq "root") {
|
||||
$sudo = "";
|
||||
}
|
||||
|
||||
# Directory where executables are on zHCP
|
||||
my $dir = "/opt/zhcp/bin";
|
||||
|
||||
# Directory where FCP disk pools are on zHCP
|
||||
my $zfcpDir = "/var/opt/zhcp/zfcp";
|
||||
|
||||
my %results = ('rc' => -1); # Default to error
|
||||
|
||||
# Check FCP device syntax
|
||||
if ($fcpDevice && ($fcpDevice !~ /^auto/i) && ($fcpDevice =~ /[^0-9a-f]/i)) {
|
||||
xCAT::zvmUtils->printLn($callback, "$header: (Error) Invalid FCP channel address $fcpDevice.");
|
||||
return;
|
||||
}
|
||||
|
||||
# Find a free FCP device based on the given range
|
||||
if ($fcpDevice =~ m/^auto/i) {
|
||||
my @ranges;
|
||||
my $min;
|
||||
my $max;
|
||||
my $found = 0;
|
||||
|
||||
if ($range =~ m/;/i) {
|
||||
@ranges = split(';', $range);
|
||||
} else {
|
||||
push(@ranges, $range);
|
||||
}
|
||||
|
||||
if (!$found) {
|
||||
# If the node has an eligible FCP device, use it
|
||||
my @deviceList = xCAT::zvmUtils->getDedicates($callback, $user, $owner);
|
||||
foreach (@deviceList) {
|
||||
# Check if this devide is eligible (among the range specified for disk $lun)
|
||||
my @info = split(' ', $_);
|
||||
my $candidate = $info[2];
|
||||
foreach (@ranges) {
|
||||
($min, $max) = split('-', $_);
|
||||
if (hex($candidate) >= hex($min) && hex($candidate) <= hex($max)) {
|
||||
$found = 1;
|
||||
$fcpDevice = uc($candidate);
|
||||
|
||||
last;
|
||||
}
|
||||
}
|
||||
|
||||
if ($found) {
|
||||
xCAT::zvmUtils->printLn($callback, "$header: Found eligible FCP channel $fcpDevice");
|
||||
last;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$found) {
|
||||
# If the node has no eligible FCP device, find a free one for it.
|
||||
my %usedDevices = xCAT::zvmUtils->getUsedFcpDevices($user, $hcp);
|
||||
|
||||
my $hcpUserId = xCAT::zvmCPUtils->getUserId($user, $hcp);
|
||||
$hcpUserId =~ tr/a-z/A-Z/;
|
||||
|
||||
# Find a free FCP channel
|
||||
my $out = `ssh $user\@$hcp "$sudo $dir/smcli System_WWPN_Query -T $hcpUserId" | egrep -i "FCP device number|Status"`;
|
||||
my @devices = split( "\n", $out );
|
||||
for (my $i = 0; $i < @devices; $i++) {
|
||||
# Extract the device number and status
|
||||
$fcpDevice = $devices[$i];
|
||||
$fcpDevice =~ s/^FCP device number:(.*)/$1/;
|
||||
$fcpDevice =~ s/^\s+//;
|
||||
$fcpDevice =~ s/\s+$//;
|
||||
|
||||
$i++;
|
||||
my $fcpStatus = $devices[$i];
|
||||
$fcpStatus =~ s/^Status:(.*)/$1/;
|
||||
$fcpStatus =~ s/^\s+//;
|
||||
$fcpStatus =~ s/\s+$//;
|
||||
|
||||
# Only look at free FCP devices
|
||||
if ($fcpStatus =~ m/free/i) {
|
||||
# If the device number is within the specified range, exit out of loop
|
||||
# Range: 3B00-3C00;4B00-4C00;5E12-5E12
|
||||
foreach (@ranges) {
|
||||
($min, $max) = split('-', $_);
|
||||
if (hex($fcpDevice) >= hex($min) && hex($fcpDevice) <= hex($max)) {
|
||||
$fcpDevice = uc($fcpDevice);
|
||||
|
||||
# Use found FCP channel if not in use or allocated
|
||||
if (!$usedDevices{$fcpDevice}) {
|
||||
$found = 1;
|
||||
last;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Break out of loop if FCP channel is found
|
||||
if ($found) {
|
||||
xCAT::zvmUtils->printLn($callback, "$header: Found FCP channel within acceptable range $fcpDevice");
|
||||
last;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Do not continue if no FCP channel is found
|
||||
if (!$found) {
|
||||
xCAT::zvmUtils->printLn($callback, "$header: (Error) A suitable FCP channel could not be found");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
# If there are multiple devices (multipathing), take the 1st one
|
||||
if ($fcpDevice) {
|
||||
if ($fcpDevice =~ m/;/i) {
|
||||
my @info = split(';', $fcpDevice);
|
||||
$fcpDevice = xCAT::zvmUtils->trimStr($info[0]);
|
||||
}
|
||||
|
||||
# Make sure channel has a length of 4
|
||||
while (length($fcpDevice) < 4) {
|
||||
$fcpDevice = "0" . $fcpDevice;
|
||||
}
|
||||
}
|
||||
|
||||
return $fcpDevice;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------
|
||||
|
||||
=head3 findzFcpDevicePool
|
||||
|
||||
Description : Find the zFCP storage pool that contains the given zFCP device
|
||||
@@ -2807,7 +2889,7 @@ sub findzFcpDevicePool {
|
||||
WWPN
|
||||
LUN
|
||||
Returns : Architecture of node
|
||||
Example : my $deviceRef = xCAT::zvmUtils->findzFcpDeviceAttr($user, $hcp, $wwpn, $lun);
|
||||
Example : my $deviceRef = xCAT::zvmUtils->findzFcpDeviceAttr($user, $hcp, $pool, $wwpn, $lun);
|
||||
|
||||
=cut
|
||||
|
||||
@@ -2827,7 +2909,7 @@ sub findzFcpDeviceAttr {
|
||||
|
||||
# Find the SCSI/FCP device
|
||||
# Entry order: status,wwpn,lun,size,range,owner,channel,tag
|
||||
my @info = split("\n", `ssh $user\@$hcp "$sudo grep \"$wwpn,$lun\" $zfcpDir/$pool.conf"`);
|
||||
my @info = split("\n", `ssh $user\@$hcp "$sudo grep -i \"$wwpn,$lun\" $zfcpDir/$pool.conf"`);
|
||||
my $entry = $info[0];
|
||||
chomp($entry);
|
||||
|
||||
|
||||
+78
-269
@@ -6,275 +6,84 @@
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <netinet/in.h>
|
||||
#include <signal.h>
|
||||
#include <syslog.h>
|
||||
|
||||
// the chunk size for each alloc
|
||||
int chunknum = 200;
|
||||
int doreload = 0;
|
||||
int verbose = 0;
|
||||
char logmsg[50];
|
||||
|
||||
// the struct to store the winpe configuration for each node
|
||||
struct nodecfg {
|
||||
char node[50];
|
||||
char data[150];
|
||||
};
|
||||
|
||||
char *data = NULL; // the ptr to the array of all node config
|
||||
int nodenum = 0;
|
||||
|
||||
// trigger the main program to reload configuration file
|
||||
void reload(int sig) {
|
||||
doreload = 1;
|
||||
}
|
||||
// the subroutine which is used to load configuration from
|
||||
// /var/lib/xcat/proxydhcp.cfg to *data
|
||||
void loadcfg () {
|
||||
nodenum = 0;
|
||||
free(data);
|
||||
data = NULL;
|
||||
doreload = 0;
|
||||
|
||||
char *dp = NULL;
|
||||
|
||||
FILE *fp;
|
||||
fp = fopen("/var/lib/xcat/proxydhcp.cfg", "r");
|
||||
if (fp) {
|
||||
int num = chunknum;
|
||||
int rtime = 1;
|
||||
while (num == chunknum) {
|
||||
// realloc the chunknum size of memory each to save memory usage
|
||||
data = realloc(data, sizeof(struct nodecfg) * chunknum * rtime);
|
||||
if (NULL == data) {
|
||||
fprintf (stderr, "Cannot get enough memory.\n");
|
||||
free (data);
|
||||
return;
|
||||
}
|
||||
dp = data + sizeof(struct nodecfg) * chunknum * (rtime - 1);
|
||||
memset(dp, 0, sizeof(struct nodecfg) * chunknum);
|
||||
num = fread(dp, sizeof (struct nodecfg), chunknum, fp);
|
||||
nodenum += num;
|
||||
rtime++;
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
// get the path of winpe from configuration file which is stored in *data
|
||||
char *getwinpepath(char *node) {
|
||||
int i;
|
||||
struct nodecfg *nc = (struct nodecfg *)data;
|
||||
for (i=0; i<nodenum;i++) {
|
||||
if (0 == strcmp(nc->node, node)) {
|
||||
return nc->data;
|
||||
}
|
||||
nc++;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int i;
|
||||
for(i = 0; i < argc; i++)
|
||||
{
|
||||
if (strcmp(argv[i], "-V") == 0) {
|
||||
verbose = 1;
|
||||
setlogmask(LOG_UPTO(LOG_DEBUG));
|
||||
openlog("proxydhcp", LOG_NDELAY, LOG_LOCAL0);
|
||||
}
|
||||
}
|
||||
|
||||
// regist my pid to /var/run/xcat/proxydhcp.pid
|
||||
int pid = getpid();
|
||||
FILE *pidf = fopen ("/var/run/xcat/proxydhcp.pid", "w");
|
||||
if (pidf) {
|
||||
fprintf(pidf, "%d", pid);
|
||||
fclose (pidf);
|
||||
} else {
|
||||
fprintf (stderr, "Cannot open /var/run/xcat/proxydhcp.pid\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// load configuration at first start
|
||||
loadcfg();
|
||||
|
||||
// regist signal SIGUSR1 for triggering reload configuration from outside
|
||||
struct sigaction sigact;
|
||||
sigact.sa_handler = &reload;
|
||||
sigaction(SIGUSR1, &sigact, NULL);
|
||||
|
||||
int serverfd,port;
|
||||
int getpktinfo = 1;
|
||||
struct addrinfo hint, *res;
|
||||
char cmsg[CMSG_SPACE(sizeof(struct in_pktinfo))];
|
||||
char clientpacket[1024];
|
||||
struct sockaddr_in clientaddr;
|
||||
struct msghdr msg;
|
||||
struct cmsghdr *cmsgptr;
|
||||
struct iovec iov[1];
|
||||
unsigned int myip, clientip;
|
||||
char *txtptr;
|
||||
iov[0].iov_base = clientpacket;
|
||||
iov[0].iov_len = 1024;
|
||||
memset(&msg,0,sizeof(msg));
|
||||
memset(&clientaddr,0,sizeof(clientaddr));
|
||||
msg.msg_name=&clientaddr;
|
||||
msg.msg_namelen = sizeof(clientaddr);
|
||||
msg.msg_iov = iov;
|
||||
msg.msg_iovlen = 1;
|
||||
msg.msg_control=&cmsg;
|
||||
msg.msg_controllen = sizeof(cmsg);
|
||||
|
||||
char defaultwinpe[20] = "Boot/bootmgfw.efi";
|
||||
char bootpmagic[4] = {0x63,0x82,0x53,0x63};
|
||||
int pktsize;
|
||||
int doexit=0;
|
||||
port = 4011;
|
||||
memset(&hint,0,sizeof(hint));
|
||||
hint.ai_family = PF_INET; /* Would've done UNSPEC, but it doesn't work right and this is heavily v4 specific anyway */
|
||||
hint.ai_socktype = SOCK_DGRAM;
|
||||
hint.ai_flags = AI_PASSIVE;
|
||||
getaddrinfo(NULL,"4011",&hint,&res);
|
||||
serverfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
|
||||
if (!serverfd) { fprintf(stderr,"That's odd...\n"); }
|
||||
setsockopt(serverfd,IPPROTO_IP,IP_PKTINFO,&getpktinfo,sizeof(getpktinfo));
|
||||
if (bind(serverfd,res->ai_addr ,res->ai_addrlen) < 0) {
|
||||
fprintf(stderr,"Unable to bind 4011");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
while (!doexit) {
|
||||
// use select to wait for the 4011 request packages coming
|
||||
fd_set fds;
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(serverfd, &fds);
|
||||
struct timeval timeout;
|
||||
timeout.tv_sec = 30;
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
int rc;
|
||||
if ((rc = select(serverfd+1,&fds,0,0, &timeout)) <= 0) {
|
||||
if (doreload) {
|
||||
loadcfg();
|
||||
fprintf(stderr, "load in select\n");
|
||||
}
|
||||
if (verbose) {syslog(LOG_DEBUG, "reload /var/lib/xcat/proxydhcp.cfg\n");}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (doreload) {
|
||||
loadcfg();
|
||||
if (verbose) {syslog(LOG_DEBUG, "reload /var/lib/xcat/proxydhcp.cfg\n");}
|
||||
}
|
||||
|
||||
pktsize = recvmsg(serverfd,&msg,0);
|
||||
if (pktsize < 320) {
|
||||
continue;
|
||||
}
|
||||
if (clientpacket[0] != 1 || memcmp(clientpacket+0xec,bootpmagic,4)) {
|
||||
continue;
|
||||
}
|
||||
for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL; cmsgptr = CMSG_NXTHDR(&msg,cmsgptr)) {
|
||||
if (cmsgptr->cmsg_level == IPPROTO_IP && cmsgptr->cmsg_type == IP_PKTINFO) {
|
||||
myip = ((struct in_pktinfo*)(CMSG_DATA(cmsgptr)))->ipi_addr.s_addr;
|
||||
}
|
||||
}
|
||||
|
||||
// get the ip of dhcp client
|
||||
clientip = 0;
|
||||
int i;
|
||||
for (i = 0; i< 4; i++) {
|
||||
clientip = clientip << 8;
|
||||
clientip += (unsigned char)clientpacket[15-i];
|
||||
}
|
||||
// get the winpe path
|
||||
struct hostent *host = gethostbyaddr(&clientip, sizeof(clientip), AF_INET);
|
||||
char *winpepath = defaultwinpe;
|
||||
if (host) {
|
||||
if (host->h_name) {
|
||||
// remove the domain part from hostname
|
||||
char *place = strstr(host->h_name, ".");
|
||||
if (place) {
|
||||
*place = '\0';
|
||||
}
|
||||
|
||||
winpepath = getwinpepath(host->h_name);
|
||||
if (winpepath == NULL) {
|
||||
winpepath = defaultwinpe;
|
||||
}
|
||||
if (verbose) {
|
||||
sprintf(logmsg, "Received proxydhcp request from %s\n", host->h_name);
|
||||
syslog(LOG_DEBUG, logmsg);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
winpepath = defaultwinpe;
|
||||
}
|
||||
|
||||
// get the Vendor class identifier
|
||||
char *arch = NULL;
|
||||
unsigned char *p = clientpacket + 0xf0;
|
||||
while (*p != 0xff && p < (unsigned char *)clientpacket + pktsize) {
|
||||
if (*p == 60) {
|
||||
arch = p + 0x11;
|
||||
break;
|
||||
} else {
|
||||
p += *(p+1) + 2;
|
||||
}
|
||||
}
|
||||
|
||||
char winboot[50]; // the bootload of winpe
|
||||
memset(winboot, 0, 50);
|
||||
if (0 == memcmp(arch, "00000", 5)) { // bios boot mode
|
||||
strcpy(winboot, winpepath);
|
||||
strcat(winboot, "Boot/pxeboot.0");
|
||||
} else if (0 == memcmp(arch, "00007", 5)) { // uefi boot mode
|
||||
strcpy(winboot, winpepath);
|
||||
strcat(winboot, "Boot/bootmgfw.efi");
|
||||
}
|
||||
|
||||
clientpacket[0] = 2; //change to a reply
|
||||
myip = htonl(myip); //endian neutral change
|
||||
clientpacket[0x14] = (myip>>24)&0xff; //maybe don't need to do this, maybe assigning the whole int would be better
|
||||
clientpacket[0x15] = (myip>>16)&0xff;
|
||||
clientpacket[0x16] = (myip>>8)&0xff;
|
||||
clientpacket[0x17] = (myip)&0xff;
|
||||
txtptr = clientpacket+0x6c;
|
||||
strncpy(txtptr, winboot ,128); // keeping 128 in there just in case someone changes the string
|
||||
//strncpy(txtptr,"winboot/new/Boot/bootmgfw.efi",128); // keeping 128 in there just in case someone changes the string
|
||||
//strncpy(txtptr,"Boot/pxeboot.0",128); // keeping 128 in there just in case someone changes the string
|
||||
clientpacket[0xf0]=0x35; //DHCP MSG type
|
||||
clientpacket[0xf1]=0x1; // LEN of 1
|
||||
clientpacket[0xf2]=0x5; //DHCP ACK
|
||||
clientpacket[0xf3]=0x36; //DHCP server identifier
|
||||
clientpacket[0xf4]=0x4; //DHCP server identifier length
|
||||
clientpacket[0xf5] = (myip>>24)&0xff; //maybe don't need to do this, maybe assigning the whole int would be better
|
||||
clientpacket[0xf6] = (myip>>16)&0xff;
|
||||
clientpacket[0xf7] = (myip>>8)&0xff;
|
||||
clientpacket[0xf8] = (myip)&0xff;
|
||||
|
||||
char winBCD[50];
|
||||
strcpy(winBCD, winpepath);
|
||||
strcat(winBCD, "Boot/BCD");
|
||||
clientpacket[0xf9] = 0xfc; // dhcp 252 'proxy', but coopeted by bootmgfw, it's actually suggesting the boot config file
|
||||
clientpacket[0xfa] = strlen(winBCD) + 1; //length of 9
|
||||
txtptr = clientpacket+0xfb;
|
||||
strncpy(txtptr, winBCD, strlen(winBCD));
|
||||
clientpacket[0xfa + strlen(winBCD) + 1] = 0;
|
||||
clientpacket[0xfa + strlen(winBCD) + 2] = 0xff;
|
||||
sendto(serverfd,clientpacket,pktsize,0,(struct sockaddr*)&clientaddr,sizeof(clientaddr));
|
||||
|
||||
if (verbose) {
|
||||
sprintf(logmsg, "Path of bootloader:%s. Path of BCD:%s\n", winboot, winBCD);
|
||||
syslog(LOG_DEBUG, logmsg);
|
||||
}
|
||||
}
|
||||
|
||||
if (verbose) { closelog();}
|
||||
int main() {
|
||||
int serverfd,port;
|
||||
int getpktinfo = 1;
|
||||
struct addrinfo hint, *res;
|
||||
char cmsg[CMSG_SPACE(sizeof(struct in_pktinfo))];
|
||||
char clientpacket[1024];
|
||||
struct sockaddr_in clientaddr;
|
||||
struct msghdr msg;
|
||||
struct cmsghdr *cmsgptr;
|
||||
struct iovec iov[1];
|
||||
unsigned int myip;
|
||||
char *txtptr;
|
||||
iov[0].iov_base = clientpacket;
|
||||
iov[0].iov_len = 1024;
|
||||
memset(&msg,0,sizeof(msg));
|
||||
memset(&clientaddr,0,sizeof(clientaddr));
|
||||
msg.msg_name=&clientaddr;
|
||||
msg.msg_namelen = sizeof(clientaddr);
|
||||
msg.msg_iov = iov;
|
||||
msg.msg_iovlen = 1;
|
||||
msg.msg_control=&cmsg;
|
||||
msg.msg_controllen = sizeof(cmsg);
|
||||
|
||||
|
||||
char bootpmagic[4] = {0x63,0x82,0x53,0x63};
|
||||
int pktsize;
|
||||
int doexit=0;
|
||||
port = 4011;
|
||||
memset(&hint,0,sizeof(hint));
|
||||
hint.ai_family = PF_INET; /* Would've done UNSPEC, but it doesn't work right and this is heavily v4 specific anyway */
|
||||
hint.ai_socktype = SOCK_DGRAM;
|
||||
hint.ai_flags = AI_PASSIVE;
|
||||
getaddrinfo(NULL,"4011",&hint,&res);
|
||||
serverfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
|
||||
if (!serverfd) { fprintf(stderr,"That's odd...\n"); }
|
||||
setsockopt(serverfd,IPPROTO_IP,IP_PKTINFO,&getpktinfo,sizeof(getpktinfo));
|
||||
if (bind(serverfd,res->ai_addr ,res->ai_addrlen) < 0) {
|
||||
fprintf(stderr,"Unable to bind 4011");
|
||||
exit(1);
|
||||
}
|
||||
while (!doexit) {
|
||||
pktsize = recvmsg(serverfd,&msg,0);
|
||||
if (pktsize < 320) {
|
||||
continue;
|
||||
}
|
||||
if (clientpacket[0] != 1 || memcmp(clientpacket+0xec,bootpmagic,4)) {
|
||||
continue;
|
||||
}
|
||||
for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL; cmsgptr = CMSG_NXTHDR(&msg,cmsgptr)) {
|
||||
if (cmsgptr->cmsg_level == IPPROTO_IP && cmsgptr->cmsg_type == IP_PKTINFO) {
|
||||
myip = ((struct in_pktinfo*)(CMSG_DATA(cmsgptr)))->ipi_addr.s_addr;
|
||||
}
|
||||
}
|
||||
clientpacket[0] = 2; //change to a reply
|
||||
myip = htonl(myip); //endian neutral change
|
||||
clientpacket[0x14] = (myip>>24)&0xff; //maybe don't need to do this, maybe assigning the whole int would be better
|
||||
clientpacket[0x15] = (myip>>16)&0xff;
|
||||
clientpacket[0x16] = (myip>>8)&0xff;
|
||||
clientpacket[0x17] = (myip)&0xff;
|
||||
txtptr = clientpacket+0x6c;
|
||||
strncpy(txtptr,"Boot/bootmgfw.efi",128); // keeping 128 in there just in case someone changes the string
|
||||
clientpacket[0xf0]=0x35; //DHCP MSG type
|
||||
clientpacket[0xf1]=0x1; // LEN of 1
|
||||
clientpacket[0xf2]=0x5; //DHCP ACK
|
||||
clientpacket[0xf3]=0x36; //DHCP server identifier
|
||||
clientpacket[0xf4]=0x4; //DHCP server identifier length
|
||||
clientpacket[0xf5] = (myip>>24)&0xff; //maybe don't need to do this, maybe assigning the whole int would be better
|
||||
clientpacket[0xf6] = (myip>>16)&0xff;
|
||||
clientpacket[0xf7] = (myip>>8)&0xff;
|
||||
clientpacket[0xf8] = (myip)&0xff;
|
||||
clientpacket[0xf9] = 0xfc; // dhcp 252 'proxy', but coopeted by bootmgfw, it's actually suggesting the boot config file
|
||||
clientpacket[0xfa] = 9; //length of 9
|
||||
txtptr = clientpacket+0xfb;
|
||||
strncpy(txtptr,"Boot/BCD",8);
|
||||
clientpacket[0x103]=0;
|
||||
clientpacket[0x104]=0xff;
|
||||
sendto(serverfd,clientpacket,pktsize,0,(struct sockaddr*)&clientaddr,sizeof(clientaddr));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
/* IBM(c) 2013 EPL licens http://www.eclipse.org/legal/epl-v10.html
|
||||
* Jarrod Johnson - jbjohnso@us.ibm.com
|
||||
* This program periodically transmits a udp packet to designated xCAT server
|
||||
* It waits for an 'ok' and then exits
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
int main(int argc, char* argv[]) {
|
||||
int server;
|
||||
struct addrinfo hints;
|
||||
struct addrinfo *results,*cur;
|
||||
struct timeval timeout;
|
||||
int canread=0;
|
||||
char buffer[128];
|
||||
srand(time(NULL));
|
||||
memset(&hints,0,sizeof(struct addrinfo));
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_DGRAM;
|
||||
hints.ai_protocol = IPPROTO_UDP;
|
||||
fd_set selectset;
|
||||
getaddrinfo(argv[1],argv[2],&hints,&results);
|
||||
server = socket(AF_UNSPEC,SOCK_DGRAM,17);
|
||||
for (cur=results; cur != NULL; cur = cur->ai_next) {
|
||||
server = socket(cur->ai_family,cur->ai_socktype,cur->ai_protocol);
|
||||
if (server == -1) continue;
|
||||
if (connect(server,cur->ai_addr,cur->ai_addrlen) != -1) break;
|
||||
close(server);
|
||||
}
|
||||
FD_ZERO(&selectset);
|
||||
FD_SET(server,&selectset);
|
||||
while (1) {
|
||||
timeout.tv_sec = rand() % 120+60;
|
||||
timeout.tv_usec = rand() % 10000;
|
||||
write(server,"resourcerequest: xcatd\n",strlen("resourcerequest: xcatd\n"));
|
||||
canread = select(FD_SETSIZE,&selectset,NULL,NULL,&timeout);
|
||||
if (canread) {
|
||||
read(server,buffer,sizeof(buffer));
|
||||
if (strncmp(buffer,"resourcerequest: ok",strlen("resourcerequest: ok"))==0) {
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
# AIX Bundle file for compiler runtime packages
|
||||
|
||||
I:xlC.aix61
|
||||
I:xlC.rte
|
||||
I:xlfrte
|
||||
I:xlfrte.aix61
|
||||
I:xlfrte.msg.en_US
|
||||
I:xlsmp.aix61.rte
|
||||
I:xlsmp.msg.en_US.rte
|
||||
I:xlsmp.rte
|
||||
@@ -14,7 +14,7 @@
|
||||
# postscript (stateful install) or with the otherpkgs processing of
|
||||
# genimage (stateless/statelite install). This script will install any
|
||||
# gpfs update rpms that exist on the xCAT management node in the
|
||||
# /install/post/otherpkgs/gpfs_updates directory.
|
||||
# /install/post/gpfs_updates directory.
|
||||
# This is necessary because the GPFS updates can ONLY be installed
|
||||
# after the base rpms have been installed, and the update rpms cannot
|
||||
# exist in any rpm repositories used by xCAT otherpkgs processing
|
||||
@@ -41,8 +41,8 @@ if [ $OS != "AIX" ]; then
|
||||
mkdir -p /tmp/gpfs_updates
|
||||
rm -f -R /tmp/gpfs_updates/*
|
||||
cd /tmp/gpfs_updates
|
||||
# wget -l inf -N -r --waitretry=10 --random-wait --retry-connrefused -t 10 -T 60 -nH --cut-dirs=3 ftp://$MASTER/$UPDATES_DIR/*.rpm 2> /tmp/wget.log
|
||||
wget -l inf -N -r --waitretry=10 --random-wait --retry-connrefused -t 10 -T 60 -nH --cut-dirs=4 --reject "index.html*" --no-parent http://$MASTER$INSTALL_DIR/$UPDATES_DIR/ 2> /tmp/wget.log
|
||||
# wget -l inf -N -r --waitretry=10 --random-wait --retry-connrefused -t 10 -T 60 -nH --cut-dirs=3 ftp://$SITEMASTER/$UPDATES_DIR/*.rpm 2> /tmp/wget.log
|
||||
wget -l inf -N -r --waitretry=10 --random-wait --retry-connrefused -t 10 -T 60 -nH --cut-dirs=4 --reject "index.html*" --no-parent http://$SITEMASTER$INSTALL_DIR/$UPDATES_DIR/ 2> /tmp/wget.log
|
||||
if [ -n "`ls *.rpm 2> /dev/null`" ] ; then
|
||||
rpm -Uvh *.rpm
|
||||
fi
|
||||
|
||||
@@ -62,8 +62,7 @@ else
|
||||
file=$1
|
||||
fi
|
||||
|
||||
#ifconfig -a | grep 'inet ' | awk ' { print $2 } ' | grep -v 127.0.0.1 |
|
||||
ip -4 -oneline addr show 2>/dev/null |grep inet | sed -ne "s/.*inet //p"|awk -F ' ' '{print $1}'|awk -F '/' '{print $1}'|
|
||||
ifconfig -a | grep 'inet ' | awk ' { print $2 } ' | grep -v 127.0.0.1 |
|
||||
while read my_address ; do
|
||||
##print "checking $my_address"
|
||||
grep -q " ${my_address}$" $file
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
xcat-openstack-baremetal for Debian
|
||||
-----------------------------------
|
||||
|
||||
<possible notes regarding this package - if none, delete this file>
|
||||
|
||||
-- root <root@unknown> Wed, 12 Mar 2014 01:47:54 -0700
|
||||
@@ -1,9 +0,0 @@
|
||||
xcat-openstack-baremetal for Debian
|
||||
-----------------------------------
|
||||
|
||||
<this file describes information about the source package, see Debian policy
|
||||
manual section 4.14. You WILL either need to modify or delete this file>
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
xcat-openstack-baremetal (2.8.4-1) unstable; urgency=low
|
||||
|
||||
* Initial release (Closes: #nnnn) <nnnn is the bug number of your ITP>
|
||||
|
||||
-- root <root@unknown> Wed, 12 Mar 2014 01:47:54 -0700
|
||||
@@ -1 +0,0 @@
|
||||
8
|
||||
@@ -1,14 +0,0 @@
|
||||
Source: xcat-openstack-baremetal
|
||||
Section: admin
|
||||
Priority: extra
|
||||
Maintainer: xCAT <xcat-user@lists.sourceforge.net>
|
||||
Build-Depends: debhelper (>= 8.0.0)
|
||||
Standards-Version: 3.9.4
|
||||
Homepage: http://xcat.sourceforge.net/
|
||||
#Vcs-Git: git://git.debian.org/collab-maint/xcat-openstack-baremetal.git
|
||||
#Vcs-Browser: http://git.debian.org/?p=collab-maint/xcat-openstack-baremetal.git;a=summary
|
||||
|
||||
Package: xcat-openstack-baremetal
|
||||
Architecture: all
|
||||
Depends: xCAT-client
|
||||
Description: Executables and data of the xCAT baremetal driver for OpenStack
|
||||
@@ -1,38 +0,0 @@
|
||||
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||
Upstream-Name: xcat-openstack-baremetal
|
||||
Source: <url://example.com>
|
||||
|
||||
Files: *
|
||||
Copyright: <years> <put author's name and email here>
|
||||
<years> <likewise for another author>
|
||||
License: <special license>
|
||||
<Put the license of the package here indented by 1 space>
|
||||
<This follows the format of Description: lines in control file>
|
||||
.
|
||||
<Including paragraphs>
|
||||
|
||||
# If you want to use GPL v2 or later for the /debian/* files use
|
||||
# the following clauses, or change it to suit. Delete these two lines
|
||||
Files: debian/*
|
||||
Copyright: 2014 root <root@unknown>
|
||||
License: GPL-2+
|
||||
This package is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
.
|
||||
This package is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
.
|
||||
On Debian systems, the complete text of the GNU General
|
||||
Public License version 2 can be found in "/usr/share/common-licenses/GPL-2".
|
||||
|
||||
# Please also look if there are files or directories which have a
|
||||
# different copyright/license attached and list them here.
|
||||
# Please avoid to pick license terms that are more restrictive than the
|
||||
# packaged work, as it may make Debian's contributions unacceptable upstream.
|
||||
@@ -1,7 +0,0 @@
|
||||
opt/xcat/bin
|
||||
opt/xcat/sbin
|
||||
opt/xcat/lib/perl/xCAT_plugin
|
||||
opt/xcat/lib/python/xcat/openstack/baremetal
|
||||
opt/xcat/share/xcat/openstack/postscripts
|
||||
opt/xcat/share/man/man1
|
||||
opt/xcat/share/doc/man1
|
||||
@@ -1,2 +0,0 @@
|
||||
xcat-openstack-baremetal_2.8.4-1_all.deb admin extra
|
||||
xcat-openstack-baremetal_2.8.4-1_all.deb admin extra
|
||||
@@ -1,6 +0,0 @@
|
||||
lib/* opt/xcat/lib/
|
||||
share/xcat/openstack/postscripts/* opt/xcat/share/xcat/openstack/postscripts/
|
||||
share/man/man1/* opt/xcat/share/man/man1/
|
||||
share/doc/man1/* opt/xcat/share/doc/man1/
|
||||
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
#!/bin/sh
|
||||
# postinst script for xcat-openstack-baremetal
|
||||
#
|
||||
# see: dh_installdeb(1)
|
||||
|
||||
set -e
|
||||
|
||||
# summary of how this script can be called:
|
||||
# * <postinst> `configure' <most-recently-configured-version>
|
||||
# * <old-postinst> `abort-upgrade' <new version>
|
||||
# * <conflictor's-postinst> `abort-remove' `in-favour' <package>
|
||||
# <new-version>
|
||||
# * <postinst> `abort-remove'
|
||||
# * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
|
||||
# <failed-install-package> <version> `removing'
|
||||
# <conflicting-package> <version>
|
||||
# for details, see http://www.debian.org/doc/debian-policy/ or
|
||||
# the debian-policy package
|
||||
|
||||
|
||||
case "$1" in
|
||||
configure)
|
||||
#copy the postscripts under /installl/postscripts directory on MN only
|
||||
if [ -f "/etc/xCATMN" ]; then
|
||||
cp /opt/xcat/share/xcat/openstack/postscripts/* /install/postscripts/
|
||||
fi
|
||||
;;
|
||||
|
||||
abort-upgrade|abort-remove|abort-deconfigure)
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "postinst called with unknown argument \`$1'" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# dh_installdeb will replace this with shell code automatically
|
||||
# generated by other debhelper scripts.
|
||||
|
||||
#DEBHELPER#
|
||||
|
||||
exit 0
|
||||
@@ -1,46 +0,0 @@
|
||||
#!/bin/sh
|
||||
# prerm script for xcat-openstack-baremetal
|
||||
#
|
||||
# see: dh_installdeb(1)
|
||||
|
||||
set -e
|
||||
|
||||
# summary of how this script can be called:
|
||||
# * <prerm> `remove'
|
||||
# * <old-prerm> `upgrade' <new-version>
|
||||
# * <new-prerm> `failed-upgrade' <old-version>
|
||||
# * <conflictor's-prerm> `remove' `in-favour' <package> <new-version>
|
||||
# * <deconfigured's-prerm> `deconfigure' `in-favour'
|
||||
# <package-being-installed> <version> `removing'
|
||||
# <conflicting-package> <version>
|
||||
# for details, see http://www.debian.org/doc/debian-policy/ or
|
||||
# the debian-policy package
|
||||
|
||||
|
||||
case "$1" in
|
||||
remove|upgrade|deconfigure)
|
||||
#remove postscripts under /installl/postscripts directory on MN only
|
||||
if [ -f "/etc/xCATMN" ]; then
|
||||
for fn in /opt/xcat/share/xcat/openstack/postscripts/*
|
||||
do
|
||||
bn=`basename $fn`
|
||||
rm /install/postscripts/$bn
|
||||
done
|
||||
fi
|
||||
;;
|
||||
|
||||
failed-upgrade)
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "prerm called with unknown argument \`$1'" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# dh_installdeb will replace this with shell code automatically
|
||||
# generated by other debhelper scripts.
|
||||
|
||||
#DEBHELPER#
|
||||
|
||||
exit 0
|
||||
@@ -1,44 +0,0 @@
|
||||
#!/usr/bin/make -f
|
||||
# -*- makefile -*-
|
||||
# Sample debian/rules that uses debhelper.
|
||||
# This file was originally written by Joey Hess and Craig Small.
|
||||
# As a special exception, when this file is copied by dh-make into a
|
||||
# dh-make output file, you may use that output file without restriction.
|
||||
# This special exception was added by Craig Small in version 0.37 of dh-make.
|
||||
|
||||
# Uncomment this to turn on verbose mode.
|
||||
#export DH_VERBOSE=1
|
||||
|
||||
build:
|
||||
pwd
|
||||
`pwd`/xpod2man
|
||||
|
||||
clean:
|
||||
dh_testdir
|
||||
dh_testroot
|
||||
dh_clean -d
|
||||
|
||||
install:
|
||||
pwd
|
||||
dh_testdir
|
||||
dh_testroot
|
||||
dh_installdirs
|
||||
dh_install -X".svn"
|
||||
chmod 444 `pwd`/debian/xcat-openstack-baremetal/opt/xcat/share/man/man1/*
|
||||
chmod 644 `pwd`/debian/xcat-openstack-baremetal/opt/xcat/share/doc/man1/*
|
||||
dh_link
|
||||
|
||||
binary-indep: build install
|
||||
pwd
|
||||
export
|
||||
dh_installman
|
||||
dh_compress
|
||||
dh_installdeb
|
||||
dh_gencontrol
|
||||
dh_md5sums
|
||||
dh_builddeb
|
||||
|
||||
binary-arch:
|
||||
pwd
|
||||
binary: binary-indep binary-arch
|
||||
.PHONY: build clean binary-indep binary-arch binary install configure
|
||||
@@ -1 +0,0 @@
|
||||
1.0
|
||||
@@ -1,201 +0,0 @@
|
||||
dh_installdirs
|
||||
dh_installdirs
|
||||
dh_install
|
||||
dh_link
|
||||
dh_installman
|
||||
dh_compress
|
||||
dh_installdeb
|
||||
dh_gencontrol
|
||||
dh_md5sums
|
||||
dh_builddeb
|
||||
dh_builddeb
|
||||
dh_installdirs
|
||||
dh_install
|
||||
dh_link
|
||||
dh_installman
|
||||
dh_compress
|
||||
dh_installdeb
|
||||
dh_gencontrol
|
||||
dh_md5sums
|
||||
dh_builddeb
|
||||
dh_builddeb
|
||||
dh_installdirs
|
||||
dh_install
|
||||
dh_link
|
||||
dh_installman
|
||||
dh_compress
|
||||
dh_installdeb
|
||||
dh_gencontrol
|
||||
dh_md5sums
|
||||
dh_builddeb
|
||||
dh_builddeb
|
||||
dh_installdirs
|
||||
dh_install
|
||||
dh_link
|
||||
dh_installman
|
||||
dh_compress
|
||||
dh_installdeb
|
||||
dh_gencontrol
|
||||
dh_md5sums
|
||||
dh_builddeb
|
||||
dh_builddeb
|
||||
dh_installdirs
|
||||
dh_install
|
||||
dh_link
|
||||
dh_installman
|
||||
dh_compress
|
||||
dh_installdeb
|
||||
dh_gencontrol
|
||||
dh_md5sums
|
||||
dh_builddeb
|
||||
dh_builddeb
|
||||
dh_installdirs
|
||||
dh_install
|
||||
dh_link
|
||||
dh_installman
|
||||
dh_compress
|
||||
dh_installdeb
|
||||
dh_gencontrol
|
||||
dh_md5sums
|
||||
dh_builddeb
|
||||
dh_builddeb
|
||||
dh_installdirs
|
||||
dh_install
|
||||
dh_link
|
||||
dh_installman
|
||||
dh_compress
|
||||
dh_installdeb
|
||||
dh_gencontrol
|
||||
dh_md5sums
|
||||
dh_builddeb
|
||||
dh_builddeb
|
||||
dh_installdirs
|
||||
dh_install
|
||||
dh_link
|
||||
dh_installman
|
||||
dh_compress
|
||||
dh_installdeb
|
||||
dh_gencontrol
|
||||
dh_md5sums
|
||||
dh_builddeb
|
||||
dh_builddeb
|
||||
dh_installdirs
|
||||
dh_install
|
||||
dh_link
|
||||
dh_installman
|
||||
dh_compress
|
||||
dh_installdeb
|
||||
dh_gencontrol
|
||||
dh_md5sums
|
||||
dh_builddeb
|
||||
dh_builddeb
|
||||
dh_installdirs
|
||||
dh_install
|
||||
dh_link
|
||||
dh_installman
|
||||
dh_compress
|
||||
dh_installdeb
|
||||
dh_gencontrol
|
||||
dh_md5sums
|
||||
dh_builddeb
|
||||
dh_builddeb
|
||||
dh_installdirs
|
||||
dh_install
|
||||
dh_link
|
||||
dh_installman
|
||||
dh_compress
|
||||
dh_installdeb
|
||||
dh_gencontrol
|
||||
dh_md5sums
|
||||
dh_builddeb
|
||||
dh_builddeb
|
||||
dh_installdirs
|
||||
dh_install
|
||||
dh_link
|
||||
dh_installman
|
||||
dh_compress
|
||||
dh_installdeb
|
||||
dh_gencontrol
|
||||
dh_md5sums
|
||||
dh_builddeb
|
||||
dh_builddeb
|
||||
dh_installdirs
|
||||
dh_install
|
||||
dh_link
|
||||
dh_installman
|
||||
dh_compress
|
||||
dh_installdeb
|
||||
dh_gencontrol
|
||||
dh_md5sums
|
||||
dh_builddeb
|
||||
dh_builddeb
|
||||
dh_installdirs
|
||||
dh_install
|
||||
dh_link
|
||||
dh_installman
|
||||
dh_compress
|
||||
dh_installdeb
|
||||
dh_gencontrol
|
||||
dh_md5sums
|
||||
dh_builddeb
|
||||
dh_builddeb
|
||||
dh_installdirs
|
||||
dh_install
|
||||
dh_link
|
||||
dh_installman
|
||||
dh_compress
|
||||
dh_installdeb
|
||||
dh_gencontrol
|
||||
dh_md5sums
|
||||
dh_builddeb
|
||||
dh_builddeb
|
||||
dh_installdirs
|
||||
dh_install
|
||||
dh_link
|
||||
dh_installman
|
||||
dh_compress
|
||||
dh_installdeb
|
||||
dh_gencontrol
|
||||
dh_md5sums
|
||||
dh_builddeb
|
||||
dh_builddeb
|
||||
dh_installdirs
|
||||
dh_install
|
||||
dh_link
|
||||
dh_installman
|
||||
dh_compress
|
||||
dh_installdeb
|
||||
dh_gencontrol
|
||||
dh_md5sums
|
||||
dh_builddeb
|
||||
dh_builddeb
|
||||
dh_installdirs
|
||||
dh_install
|
||||
dh_link
|
||||
dh_installman
|
||||
dh_compress
|
||||
dh_installdeb
|
||||
dh_gencontrol
|
||||
dh_md5sums
|
||||
dh_builddeb
|
||||
dh_builddeb
|
||||
dh_installdirs
|
||||
dh_install
|
||||
dh_link
|
||||
dh_installman
|
||||
dh_compress
|
||||
dh_installdeb
|
||||
dh_gencontrol
|
||||
dh_md5sums
|
||||
dh_builddeb
|
||||
dh_builddeb
|
||||
dh_installdirs
|
||||
dh_install
|
||||
dh_link
|
||||
dh_installman
|
||||
dh_compress
|
||||
dh_installdeb
|
||||
dh_gencontrol
|
||||
dh_md5sums
|
||||
dh_builddeb
|
||||
dh_builddeb
|
||||
@@ -1,4 +0,0 @@
|
||||
opt/xcat/bin/xcatclient opt/xcat/sbin/deploy_ops_bm_node
|
||||
opt/xcat/bin/xcatclient opt/xcat/sbin/cleanup_ops_bm_node
|
||||
opt/xcat/bin/xcatclient opt/xcat/bin/opsaddbmnode
|
||||
opt/xcat/bin/xcatclientnnr opt/xcat/bin/opsaddimage
|
||||
@@ -1 +0,0 @@
|
||||
misc:Depends=
|
||||
@@ -1,965 +0,0 @@
|
||||
# IBM(c) 2013 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
package xCAT_plugin::openstack;
|
||||
BEGIN
|
||||
{
|
||||
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
|
||||
}
|
||||
use lib "$::XCATROOT/lib/perl";
|
||||
use xCAT::Utils;
|
||||
use xCAT::TableUtils;
|
||||
use xCAT::SvrUtils;
|
||||
use xCAT::NetworkUtils;
|
||||
use xCAT::Table;
|
||||
use Data::Dumper;
|
||||
use File::Path;
|
||||
use File::Copy;
|
||||
use Getopt::Long;
|
||||
Getopt::Long::Configure("bundling");
|
||||
Getopt::Long::Configure("pass_through");
|
||||
|
||||
|
||||
sub handled_commands {
|
||||
return {
|
||||
opsaddbmnode => "openstack", #external command
|
||||
opsaddimage => "openstack", #external command
|
||||
deploy_ops_bm_node => "openstack", #internal command called from the baremetal driver
|
||||
cleanup_ops_bm_node => "openstack", #internal command called from the baremetal driver
|
||||
}
|
||||
}
|
||||
|
||||
sub process_request {
|
||||
my $request = shift;
|
||||
my $callback = shift;
|
||||
my $doreq = shift;
|
||||
my $command = $request->{command}->[0];
|
||||
|
||||
if ($command eq "opsaddbmnode") {
|
||||
return opsaddbmnode($request, $callback, $doreq);
|
||||
} elsif ($command eq "opsaddimage") {
|
||||
return opsaddimage($request, $callback, $doreq);
|
||||
} elsif ($command eq "deploy_ops_bm_node") {
|
||||
return deploy_ops_bm_node($request, $callback, $doreq);
|
||||
} elsif ($command eq "cleanup_ops_bm_node") {
|
||||
return cleanup_ops_bm_node($request, $callback, $doreq);
|
||||
} else {
|
||||
$callback->({error=>["Unsupported command: $command."],errorcode=>[1]});
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
=head3 opsaddbmnode
|
||||
This function takes the xCAT nodes and register them
|
||||
as the OpenStack baremetal nodes
|
||||
=cut
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
sub opsaddbmnode {
|
||||
my $request = shift;
|
||||
my $callback = shift;
|
||||
my $doreq = shift;
|
||||
|
||||
@ARGV = @{$request->{arg}};
|
||||
Getopt::Long::Configure("bundling");
|
||||
Getopt::Long::Configure("no_pass_through");
|
||||
|
||||
my $help;
|
||||
my $version;
|
||||
my $verbose;
|
||||
my $host;
|
||||
|
||||
if(!GetOptions(
|
||||
'h|help' => \$help,
|
||||
'v|version' => \$version,
|
||||
'V|verbose' => \$verbose,
|
||||
's=s' => \$host,
|
||||
))
|
||||
{
|
||||
&opsaddbmnode_usage($callback);
|
||||
return 1;
|
||||
}
|
||||
# display the usage if -h or --help is specified
|
||||
if ($help) {
|
||||
&opsaddbmnode_usage($callback);
|
||||
return 0;
|
||||
}
|
||||
# display the version statement if -v or --verison is specified
|
||||
if ($version)
|
||||
{
|
||||
my $rsp={};
|
||||
$rsp->{data}->[0]= xCAT::Utils->Version();
|
||||
$callback->($rsp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!$request->{node}) {
|
||||
$callback->({error=>["Please specify at least one node."],errorcode=>[1]});
|
||||
return 1;
|
||||
}
|
||||
if (!$host) {
|
||||
$callback->({error=>["Please specify the OpenStack compute host name with -s flag."],errorcode=>[1]});
|
||||
return 1;
|
||||
}
|
||||
|
||||
my $nodes = $request->{node};
|
||||
|
||||
#get node mgt
|
||||
my $nodehmhash;
|
||||
my $nodehmtab = xCAT::Table->new("nodehm");
|
||||
if ($nodehmtab) {
|
||||
$nodehmhash = $nodehmtab->getNodesAttribs($nodes,['power', 'mgt']);
|
||||
}
|
||||
|
||||
#get bmc info for the nodes
|
||||
my $ipmitab = xCAT::Table->new("ipmi", -create => 0);
|
||||
my $tmp_ipmi;
|
||||
if ($ipmitab) {
|
||||
$tmp_ipmi = $ipmitab->getNodesAttribs($nodes, ['bmc','username', 'password'], prefetchcache=>1);
|
||||
#print Dumper($tmp_ipmi);
|
||||
} else {
|
||||
$callback->({error=>["Cannot open the ipmi table."],errorcode=>[1]});
|
||||
return 1;
|
||||
}
|
||||
|
||||
#get mac for the nodes
|
||||
my $mactab = xCAT::Table->new("mac", -create => 0);
|
||||
my $tmp_mac;
|
||||
if ($mactab) {
|
||||
$tmp_mac = $mactab->getNodesAttribs($nodes, ['mac'], prefetchcache=>1);
|
||||
#print Dumper($tmp_mac);
|
||||
} else {
|
||||
$callback->({error=>["Cannot open the mac table."],errorcode=>[1]});
|
||||
return 1;
|
||||
}
|
||||
|
||||
#get cpu, memory and disk info for the nodes
|
||||
my $hwinvtab = xCAT::Table->new("hwinv", -create => 0);
|
||||
my $tmp_hwinv;
|
||||
if ($hwinvtab) {
|
||||
$tmp_hwinv = $hwinvtab->getNodesAttribs($nodes, ['cpucount', 'memory', 'disksize'], prefetchcache=>1);
|
||||
#print Dumper($tmp_hwinv);
|
||||
} else {
|
||||
$callback->({error=>["Cannot open the hwinv table."],errorcode=>[1]});
|
||||
return 1;
|
||||
}
|
||||
|
||||
#get default username and password for bmc
|
||||
my $d_bmcuser;
|
||||
my $d_bmcpasswd;
|
||||
my $passtab = xCAT::Table->new('passwd');
|
||||
if ($passtab) {
|
||||
($tmp_passwd)=$passtab->getAttribs({'key'=>'ipmi'},'username','password');
|
||||
if (defined($tmp_passwd)) {
|
||||
$d_bmcuser = $tmp_passwd->{username};
|
||||
$d_bmcpasswd = $tmp_passwd->{password};
|
||||
}
|
||||
}
|
||||
|
||||
#print "d_bmcuser=$d_bmcuser, d_bmcpasswd=$d_bmcpasswd \n";
|
||||
foreach my $node (@$nodes) {
|
||||
#collect the node infomation needed for each node, some info
|
||||
my $mgt;
|
||||
my $ref_nodehm = $nodehmhash->{$node}->[0];
|
||||
if ($ref_nodehm) {
|
||||
if ($ref_nodehm->{'power'}) {
|
||||
$mgt = $ref_nodehm->{'power'};
|
||||
} elsif ($ref_nodehm->{'mgt'}) {
|
||||
$mgt = $ref_nodehm->{'mgt'};
|
||||
}
|
||||
}
|
||||
|
||||
my ($bmc, $bmc_user, $bmc_password, $mac, $cpu, $memory, $disk);
|
||||
if (($mgt) && ($mgt eq 'ipmi')) {
|
||||
my $ref_ipmi = $tmp_ipmi->{$node}->[0];
|
||||
if ($ref_ipmi) {
|
||||
if (exists($ref_ipmi->{bmc})) {
|
||||
$bmc = $ref_ipmi->{bmc};
|
||||
}
|
||||
if (exists($ref_ipmi->{username})) {
|
||||
$bmc_user = $ref_ipmi->{username};
|
||||
if (exists($ref_ipmi->{password})) {
|
||||
$bmc_password = $ref_ipmi->{password};
|
||||
}
|
||||
} else { #take the default if they cannot be found on ipmi table
|
||||
if ($d_bmcuser) { $bmc_user = $d_bmcuser; }
|
||||
if ($d_bmcpasswd) { $bmc_password = $d_bmcpasswd; }
|
||||
}
|
||||
}
|
||||
} # else { # for hardware control point other than ipmi, just fake it in OpenStack.
|
||||
#$bmc = "0.0.0.0";
|
||||
#$bmc_user = "xCAT";
|
||||
#$bmc_password = "xCAT";
|
||||
#}
|
||||
|
||||
my $ref_mac = $tmp_mac->{$node}->[0];
|
||||
if ($ref_mac) {
|
||||
if (exists($ref_mac->{mac})) {
|
||||
$mac = $ref_mac->{mac};
|
||||
}
|
||||
}
|
||||
|
||||
$ref_hwinv = $tmp_hwinv->{$node}->[0];
|
||||
if ($ref_hwinv) {
|
||||
if (exists($ref_hwinv->{cpucount})) {
|
||||
$cpu = $ref_hwinv->{cpucount};
|
||||
}
|
||||
if (exists($ref_hwinv->{memory})) {
|
||||
$memory = $ref_hwinv->{memory};
|
||||
#TODO: what if the unit is not in MB? We need to convert it to MB
|
||||
$memory =~ s/MB|mb//g;
|
||||
}
|
||||
if (exists($ref_hwinv->{disksize})) {
|
||||
#The format of the the disk size is: sda:250GB,sdb:250GB or just 250GB
|
||||
#We need to get the size of the first one
|
||||
$disk = $ref_hwinv->{disksize};
|
||||
my @a = split(',', $disk);
|
||||
my @b = split(':', $a[0]);
|
||||
if (@b > 1) {
|
||||
$disk = $b[1];
|
||||
} else {
|
||||
$disk = $b[0];
|
||||
}
|
||||
#print "a=@a, b=@b\n";
|
||||
#TODO: what if the unit is not in GB? We need to convert it to MB
|
||||
$disk =~ s/GB|gb//g;
|
||||
}
|
||||
}
|
||||
|
||||
#some info are mendatory
|
||||
if (!$mac) {
|
||||
$callback->({error=>["Mac address is not defined in the mac table for node $node."],errorcode=>[1]});
|
||||
next;
|
||||
}
|
||||
if (!$cpu) {
|
||||
#default cpu count is 1
|
||||
$cpu = 1;
|
||||
}
|
||||
if (!$memory) {
|
||||
#default memory size is 1024MB=1GB
|
||||
$memory = 1024;
|
||||
}
|
||||
if (!$disk) {
|
||||
#default disk size is 1GB
|
||||
$disk = 1;
|
||||
}
|
||||
|
||||
if ($verbose) {
|
||||
my $rsp;
|
||||
push @{$rsp->{data}}, "Attributes gathered from the xCAT database:";
|
||||
push @{$rsp->{data}}, " bmc=$bmc";
|
||||
push @{$rsp->{data}}, " bmc_user=$bmc_user";
|
||||
push @{$rsp->{data}}, " bmc_password=$bmc_password";
|
||||
push @{$rsp->{data}}, " mac=$mac";
|
||||
push @{$rsp->{data}}, " cpu=$cpu";
|
||||
push @{$rsp->{data}}, " memory=$memory";
|
||||
push @{$rsp->{data}}, " disk=$disk";
|
||||
xCAT::MsgUtils->message("I", $rsp, $callback);
|
||||
}
|
||||
|
||||
#call OpenStack command to add the node into the OpenStack as
|
||||
#a baremetal node.
|
||||
my $cmd_tmp = "nova baremetal-node-create";
|
||||
if ($bmc) {
|
||||
#make sure it is an ip address
|
||||
if (($bmc !~ /\d+\.\d+\.\d+\.\d+/) && ($bmc !~ /:/)) {
|
||||
$bmc = xCAT::NetworkUtils->getipaddr($bmc);
|
||||
}
|
||||
$cmd_tmp .= " --pm_address=$bmc";
|
||||
}
|
||||
if ($bmc_user) {
|
||||
$cmd_tmp .= " --pm_user=$bmc_user";
|
||||
}
|
||||
if ($bmc_password) {
|
||||
$cmd_tmp .= " --pm_password=$bmc_password";
|
||||
}
|
||||
$cmd_tmp .= " $host $cpu $memory $disk $mac";
|
||||
|
||||
my $cmd = qq~$cmd_tmp~;
|
||||
if ($verbose) {
|
||||
my $rsp;
|
||||
push @{$rsp->{data}}, "The command to run on $host:";
|
||||
push @{$rsp->{data}}, " $cmd";
|
||||
push @{$rsp->{data}}, " ";
|
||||
xCAT::MsgUtils->message("I", $rsp, $callback);
|
||||
}
|
||||
#print "cmd=$cmd\n";
|
||||
my $output =
|
||||
xCAT::InstUtils->xcmd($callback, $doreq, "xdsh", [$host], $cmd, 0);
|
||||
if ($::RUNCMD_RC != 0) {
|
||||
my $rsp;
|
||||
push @{$rsp->{data}}, "OpenStack creating baremetal node $node:";
|
||||
push @{$rsp->{data}}, "$output";
|
||||
push @{$rsp->{data}}, "The command was: $cmd";
|
||||
xCAT::MsgUtils->message("E", $rsp, $callback);
|
||||
} else {
|
||||
if (($verbose) && ($output)) {
|
||||
my $rsp;
|
||||
push @{$rsp->{data}}, "$output";
|
||||
push @{$rsp->{data}}, " ";
|
||||
xCAT::MsgUtils->message("I", $rsp, $callback);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
=head3 opsaddimage
|
||||
This function takes the xCAT nodes and register them
|
||||
as the OpenStack baremetal nodes
|
||||
=cut
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
sub opsaddimage {
|
||||
my $request = shift;
|
||||
my $callback = shift;
|
||||
my $doreq = shift;
|
||||
|
||||
@ARGV = @{$request->{arg}};
|
||||
Getopt::Long::Configure("bundling");
|
||||
Getopt::Long::Configure("no_pass_through");
|
||||
|
||||
my $help;
|
||||
my $version;
|
||||
my $verbose;
|
||||
#my $cloud;
|
||||
my $ops_img_names;
|
||||
my $controller;
|
||||
|
||||
if(!GetOptions(
|
||||
'h|help' => \$help,
|
||||
'v|version' => \$version,
|
||||
'V|verbose' => \$verbose,
|
||||
'c=s' => \$controller,
|
||||
'n=s' => \$ops_img_names,
|
||||
))
|
||||
{
|
||||
&opsaddimage_usage($callback);
|
||||
return 1;
|
||||
}
|
||||
# display the usage if -h or --help is specified
|
||||
if ($help) {
|
||||
&opsaddimage_usage($callback);
|
||||
return 0;
|
||||
}
|
||||
# display the version statement if -v or --verison is specified
|
||||
if ($version)
|
||||
{
|
||||
my $rsp={};
|
||||
$rsp->{data}->[0]= xCAT::Utils->Version();
|
||||
$callback->($rsp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (@ARGV ==0) {
|
||||
$callback->({error=>["Please specify an image name or a list of image names."],errorcode=>[1]});
|
||||
return 1;
|
||||
}
|
||||
|
||||
#make sure the input cloud name is valid.
|
||||
#if (!$cloud) {
|
||||
# $callback->({error=>["Please specify the name of the cloud with -c flag."],errorcode=>[1]});
|
||||
# return 1;
|
||||
#} else {
|
||||
# my $cloudstab = xCAT::Table->new('clouds', -create => 0);
|
||||
# my @et = $cloudstab->getAllAttribs('name', 'controller');
|
||||
# if(@et) {
|
||||
# foreach my $tmp_et (@et) {
|
||||
# if ($tmp_et->{name} eq $cloud) {
|
||||
# if ($tmp_et->{controller}) {
|
||||
# $controller = $tmp_et->{controller};
|
||||
# last;
|
||||
# } else {
|
||||
# $callback->({error=>["Please specify the controller in the clouds table for the cloud: $cloud."],errorcode=>[1]});
|
||||
# return 1;
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
|
||||
if (!$controller) {
|
||||
$callback->({error=>["Please specify the OpenStack controller node name with -c."],errorcode=>[1]});
|
||||
return 1;
|
||||
}
|
||||
#}
|
||||
|
||||
#make sure that the images from the command are valid image names
|
||||
@images = split(',', $ARGV[0]);
|
||||
@new_names = ();
|
||||
if ($ops_img_names) {
|
||||
@new_names = split(',', $ops_img_names);
|
||||
}
|
||||
#print "images=@images, new image names=@new_names, controller=$controller\n";
|
||||
|
||||
my $image_hash = {};
|
||||
my $osimgtab = xCAT::Table->new('osimage', -create => 0);
|
||||
my @et = $osimgtab->getAllAttribs('imagename');
|
||||
if(@et) {
|
||||
foreach my $tmp_et (@et) {
|
||||
$image_hash->{$tmp_et->{imagename}}{'xCAT'} = 1;
|
||||
}
|
||||
}
|
||||
my @bad_images;
|
||||
foreach my $image (@images) {
|
||||
if (!exists($image_hash->{$image})) {
|
||||
push @bad_images, $image;
|
||||
}
|
||||
}
|
||||
if (@bad_images > 0) {
|
||||
$callback->({error=>["The following images cannot be found in xCAT osimage table:\n " . join("\n ", @bad_images) . "\n"],errorcode=>[1]});
|
||||
return 1;
|
||||
}
|
||||
|
||||
my $index=0;
|
||||
foreach my $image (@images) {
|
||||
my $new_name = shift(@new_names);
|
||||
if (!$new_name) {
|
||||
$new_name = $image; #the default new name is xCAT image name
|
||||
}
|
||||
my $cmd_tmp = "glance image-create --name $new_name --public --disk-format qcow2 --container-format bare --property xcat_image_name=\'$image\' < /tmp/$image.qcow2";
|
||||
|
||||
my $cmd = qq~touch /tmp/$image.qcow2;$cmd_tmp~;
|
||||
if ($verbose) {
|
||||
my $rsp;
|
||||
push @{$rsp->{data}}, "The command to run on $controller:";
|
||||
push @{$rsp->{data}}, " $cmd";
|
||||
push @{$rsp->{data}}, " ";
|
||||
xCAT::MsgUtils->message("I", $rsp, $callback);
|
||||
}
|
||||
my $output =
|
||||
xCAT::InstUtils->xcmd($callback, $doreq, "xdsh", [$controller], $cmd, 0);
|
||||
if ($::RUNCMD_RC != 0) {
|
||||
my $rsp;
|
||||
push @{$rsp->{data}}, "OpenStack creating image $new_name:";
|
||||
push @{$rsp->{data}}, "$output";
|
||||
push @{$rsp->{data}}, "The command was: $cmd";
|
||||
xCAT::MsgUtils->message("E", $rsp, $callback);
|
||||
} else {
|
||||
if (($verbose) && ($output)) {
|
||||
my $rsp;
|
||||
push @{$rsp->{data}}, "$output";
|
||||
push @{$rsp->{data}}, " ";
|
||||
xCAT::MsgUtils->message("I", $rsp, $callback);
|
||||
}
|
||||
}
|
||||
my $cmd1 = qq~rm /tmp/$image.qcow2~;
|
||||
if ($verbose) {
|
||||
my $rsp;
|
||||
push @{$rsp->{data}}, "The command to run on $controller:";
|
||||
push @{$rsp->{data}}, " $cmd1";
|
||||
push @{$rsp->{data}}, " ";
|
||||
xCAT::MsgUtils->message("I", $rsp, $callback);
|
||||
}
|
||||
my $output1 =
|
||||
xCAT::InstUtils->xcmd($callback, $doreq, "xdsh", [$controller], $cmd1, 0);
|
||||
if (($verbose) && ($output1)) {
|
||||
my $rsp;
|
||||
push @{$rsp->{data}}, "$output1";
|
||||
push @{$rsp->{data}}, " ";
|
||||
xCAT::MsgUtils->message("I", $rsp, $callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
=head3 deploy_ops_bm_node
|
||||
This is a internel command called by OpenStack xCAT-baremetal driver.
|
||||
It prepares the node by adding the config_ops_bm_node postbootscript
|
||||
to the postscript table for the node, then call nodeset and then boot
|
||||
the node up.
|
||||
=cut
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
sub deploy_ops_bm_node {
|
||||
my $request = shift;
|
||||
my $callback = shift;
|
||||
my $doreq = shift;
|
||||
|
||||
@ARGV = @{$request->{arg}};
|
||||
Getopt::Long::Configure("bundling");
|
||||
Getopt::Long::Configure("no_pass_through");
|
||||
|
||||
my $node = $request->{node}->[0];
|
||||
|
||||
my $help;
|
||||
my $version;
|
||||
my $img_name;
|
||||
my $hostname;
|
||||
my $fixed_ip;
|
||||
my $netmask;
|
||||
|
||||
if(!GetOptions(
|
||||
'h|help' => \$help,
|
||||
'v|version' => \$version,
|
||||
'image=s' => \$img_name,
|
||||
'host=s' => \$hostname,
|
||||
'ip=s' => \$fixed_ip,
|
||||
'mask=s' => \$netmask,
|
||||
))
|
||||
{
|
||||
&deploy_ops_bm_node_usage($callback);
|
||||
return 1;
|
||||
}
|
||||
# display the usage if -h or --help is specified
|
||||
if ($help) {
|
||||
&deploy_ops_bm_node_usage($callback);
|
||||
return 0;
|
||||
}
|
||||
# display the version statement if -v or --verison is specified
|
||||
if ($version)
|
||||
{
|
||||
my $rsp={};
|
||||
$rsp->{data}->[0]= xCAT::Utils->Version();
|
||||
$callback->($rsp);
|
||||
return 0;
|
||||
}
|
||||
#print "node=$node, image=$img_name, host=$hostname, ip=$fixed_ip, mask=$netmask\n";
|
||||
|
||||
#validate the image name
|
||||
my $osimagetab = xCAT::Table->new('osimage', -create=>1);
|
||||
my $ref = $osimagetab->getAttribs({imagename => $img_name}, 'imagename');
|
||||
if (!$ref) {
|
||||
$callback->({error=>["Invalid image name: $img_name."],errorcode=>[1]});
|
||||
return 1;
|
||||
}
|
||||
|
||||
#check if the fixed ip is within the xCAT management network.
|
||||
#get the master ip address for the node then check if the master ip and
|
||||
#the OpenStack fixed_ip are on the same subnet.
|
||||
#my $same_nw = 0;
|
||||
#my $master = xCAT::TableUtils->GetMasterNodeName($node);
|
||||
#my $master_ip = xCAT::NetworkUtils->toIP($master);
|
||||
#if (xCAT::NetworkUtils::isInSameSubnet($master_ip, $fixed_ip, $netmask, 0)) {
|
||||
# $same_nw = 1;
|
||||
#}
|
||||
|
||||
|
||||
#add config_ops_bm_node to the node's postbootscript
|
||||
my $script = "config_ops_bm_node $hostname $fixed_ip $netmask";
|
||||
add_postscript($callback, $node, $script);
|
||||
|
||||
#run nodeset
|
||||
my $cmd = qq~osimage=$img_name~;
|
||||
my $output = xCAT::Utils->runxcmd(
|
||||
{command => ["nodeset"],
|
||||
node => [$node],
|
||||
arg => [$cmd]},
|
||||
$doreq, -1, 1);
|
||||
if ($::RUNCMD_RC != 0) {
|
||||
my $rsp;
|
||||
push @{$rsp->{data}}, "nodeset:";
|
||||
push @{$rsp->{data}}, "$output";
|
||||
xCAT::MsgUtils->message("E", $rsp, $callback);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#deploy the node now, supported nodehm.mgt values: ipmi, blade,fsp, hmc.
|
||||
my $hmtab = xCAT::Table->new('nodehm');
|
||||
my $hment = $hmtab->getNodeAttribs($node,['mgt']);
|
||||
if ($hment && $hment->{'mgt'}) {
|
||||
my $mgt = $hment->{'mgt'};
|
||||
if ($mgt eq 'ipmi') {
|
||||
deploy_bmc_node($callback, $doreq, $node);
|
||||
} elsif (($mgt eq 'blade') || ($mgt eq 'fsp')) {
|
||||
deploy_blade($callback, $doreq, $node);
|
||||
} elsif ($mgt eq 'hmc') {
|
||||
deploy_hmc_node($callback, $doreq, $node);
|
||||
} else {
|
||||
my $rsp;
|
||||
push @{$rsp->{data}}, "Node $node: nodehm.mgt=$mgt is not supported in the OpenStack cloud.";
|
||||
xCAT::MsgUtils->message("E", $rsp, $callback);
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
#nodehm.mgt must setup for node
|
||||
my $rsp;
|
||||
push @{$rsp->{data}}, "Node $node: nodehm.mgt cannot be empty in order to deploy.";
|
||||
xCAT::MsgUtils->message("E", $rsp, $callback);
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
# Deploy a rack-mounted node
|
||||
sub deploy_bmc_node {
|
||||
my $callback = shift;
|
||||
my $doreq = shift;
|
||||
my $node = shift;
|
||||
|
||||
#set boot order
|
||||
my $cmd = qq~net~;
|
||||
my $output = xCAT::Utils->runxcmd(
|
||||
{command => ["rsetboot"],
|
||||
node => [$node],
|
||||
arg => [$cmd]},
|
||||
$doreq, -1, 1);
|
||||
if ($::RUNCMD_RC != 0) {
|
||||
my $rsp;
|
||||
push @{$rsp->{data}}, "rsetboot:";
|
||||
push @{$rsp->{data}}, "$output";
|
||||
xCAT::MsgUtils->message("E", $rsp, $callback);
|
||||
}
|
||||
|
||||
#reboot the node
|
||||
my $cmd = qq~boot~;
|
||||
my $output = xCAT::Utils->runxcmd(
|
||||
{command => ["rpower"],
|
||||
node => [$node],
|
||||
arg => [$cmd]},
|
||||
$doreq, -1, 1);
|
||||
if ($::RUNCMD_RC != 0) {
|
||||
my $rsp;
|
||||
push @{$rsp->{data}}, "rpower:";
|
||||
push @{$rsp->{data}}, "$output";
|
||||
xCAT::MsgUtils->message("E", $rsp, $callback);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
# Deploy a blade or fsp controlled node
|
||||
sub deploy_blade {
|
||||
my $callback = shift;
|
||||
my $doreq = shift;
|
||||
my $node = shift;
|
||||
|
||||
#set boot order
|
||||
my $cmd = qq~net~;
|
||||
my $output = xCAT::Utils->runxcmd(
|
||||
{command => ["rbootseq"],
|
||||
node => [$node],
|
||||
arg => [$cmd]},
|
||||
$doreq, -1, 1);
|
||||
if ($::RUNCMD_RC != 0) {
|
||||
my $rsp;
|
||||
push @{$rsp->{data}}, "rbootseq:";
|
||||
push @{$rsp->{data}}, "$output";
|
||||
xCAT::MsgUtils->message("E", $rsp, $callback);
|
||||
}
|
||||
|
||||
#reboot the node
|
||||
my $cmd = qq~boot~;
|
||||
my $output = xCAT::Utils->runxcmd(
|
||||
{command => ["rpower"],
|
||||
node => [$node],
|
||||
arg => [$cmd]},
|
||||
$doreq, -1, 1);
|
||||
if ($::RUNCMD_RC != 0) {
|
||||
my $rsp;
|
||||
push @{$rsp->{data}}, "rpower:";
|
||||
push @{$rsp->{data}}, "$output";
|
||||
xCAT::MsgUtils->message("E", $rsp, $callback);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
# Deploy a node controlled by HMC
|
||||
sub deploy_hmc_node {
|
||||
my $callback = shift;
|
||||
my $doreq = shift;
|
||||
my $node = shift;
|
||||
|
||||
my $output = xCAT::Utils->runxcmd(
|
||||
{command => ["rnetboot"],
|
||||
node => [$node]},
|
||||
$doreq, -1, 1);
|
||||
if ($::RUNCMD_RC != 0) {
|
||||
my $rsp;
|
||||
push @{$rsp->{data}}, "rnetboot:";
|
||||
push @{$rsp->{data}}, "$output";
|
||||
xCAT::MsgUtils->message("E", $rsp, $callback);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
=head3 cleanup_ops_bm_node
|
||||
This is a internel command called by OpenStack xCAT-baremetal driver.
|
||||
It undoes all the changes made by deploy_ops_bm_node command. It removes
|
||||
the config_ops_bmn_ode postbootscript from the postscript table for the
|
||||
node, removes the alias ip and then power off the node.
|
||||
=cut
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
sub cleanup_ops_bm_node {
|
||||
my $request = shift;
|
||||
my $callback = shift;
|
||||
my $doreq = shift;
|
||||
|
||||
@ARGV = @{$request->{arg}};
|
||||
Getopt::Long::Configure("bundling");
|
||||
Getopt::Long::Configure("no_pass_through");
|
||||
|
||||
my $node = $request->{node}->[0];
|
||||
|
||||
my $help;
|
||||
my $version;
|
||||
my $fixed_ip;
|
||||
|
||||
if(!GetOptions(
|
||||
'h|help' => \$help,
|
||||
'v|version' => \$version,
|
||||
'ip=s' => \$fixed_ip,
|
||||
))
|
||||
{
|
||||
&cleanup_ops_bm_node_usage($callback);
|
||||
return 1;
|
||||
}
|
||||
# display the usage if -h or --help is specified
|
||||
if ($help) {
|
||||
&cleanup_ops_bm_node_usage($callback);
|
||||
return 0;
|
||||
}
|
||||
# display the version statement if -v or --verison is specified
|
||||
if ($version)
|
||||
{
|
||||
my $rsp={};
|
||||
$rsp->{data}->[0]= xCAT::Utils->Version();
|
||||
$callback->($rsp);
|
||||
return 0;
|
||||
}
|
||||
#print "node=$node, ip=$fixed_ip\n";
|
||||
|
||||
#removes the config_ops_bm_node postbootscript from the postscripts table
|
||||
remove_postscript($callback, $node, "config_ops_bm_node");
|
||||
|
||||
|
||||
#run updatenode to remove the ip alias
|
||||
my $cmd = qq~-P deconfig_ops_bm_node $fixed_ip~;
|
||||
my $output = xCAT::Utils->runxcmd(
|
||||
{command => ["updatenode"],
|
||||
node => [$node],
|
||||
arg => [$cmd]},
|
||||
$doreq, -1, 1);
|
||||
if ($::RUNCMD_RC != 0) {
|
||||
my $rsp;
|
||||
push @{$rsp->{data}}, "updatenode:";
|
||||
push @{$rsp->{data}}, "$output";
|
||||
xCAT::MsgUtils->message("E", $rsp, $callback);
|
||||
}
|
||||
|
||||
#turn the node power off
|
||||
$ssh_ok = 0;
|
||||
my $cmd = qq~stat~;
|
||||
my $output = xCAT::Utils->runxcmd(
|
||||
{command => ["rpower"],
|
||||
node => [$node],
|
||||
arg => [$cmd]},
|
||||
$doreq, -1, 1);
|
||||
|
||||
if ($::RUNCMD_RC != 0) {
|
||||
my $rsp;
|
||||
push @{$rsp->{data}}, "rpower:";
|
||||
push @{$rsp->{data}}, "$output";
|
||||
xCAT::MsgUtils->message("E", $rsp, $callback);
|
||||
return 1;
|
||||
} else {
|
||||
if ($output !~ /: off/) {
|
||||
#power off the node
|
||||
my $cmd = qq~off~;
|
||||
my $output = xCAT::Utils->runxcmd(
|
||||
{command => ["rpower"],
|
||||
node => [$node],
|
||||
arg => [$cmd]},
|
||||
$doreq, -1, 1);
|
||||
if ($::RUNCMD_RC != 0) {
|
||||
my $rsp;
|
||||
push @{$rsp->{data}}, "rpower:";
|
||||
push @{$rsp->{data}}, "$output";
|
||||
xCAT::MsgUtils->message("E", $rsp, $callback);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------
|
||||
=head3 add_postscript
|
||||
|
||||
It adds the 'config_ops_bm_node' postbootscript to the
|
||||
postscript table for the given node.
|
||||
|
||||
=cut
|
||||
#-------------------------------------------------------
|
||||
sub add_postscript {
|
||||
my $callback=shift;
|
||||
my $node=shift;
|
||||
my $script=shift;
|
||||
#print "script=$script\n";
|
||||
|
||||
my $posttab=xCAT::Table->new("postscripts", -create =>1);
|
||||
my %setup_hash;
|
||||
my $ref = $posttab->getNodeAttribs($node,[qw(postscripts postbootscripts)]);
|
||||
my $found=0;
|
||||
if ($ref) {
|
||||
if (exists($ref->{postscripts})) {
|
||||
my @a = split(/,/, $ref->{postscripts});
|
||||
if (grep(/^config_ops_bm_node/, @a)) {
|
||||
$found = 1;
|
||||
if (!grep(/^$script$/, @a)) {
|
||||
#not exact match, must replace it with the new script
|
||||
for (@a) {
|
||||
s/^config_ops_bm_node.*$/$script/;
|
||||
}
|
||||
my $new_post = join(',', @a);
|
||||
$setup_hash{$node}={postscripts=>"$new_post"};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (exists($ref->{postbootscripts})) {
|
||||
my $post=$ref->{postbootscripts};
|
||||
my @old_a=split(',', $post);
|
||||
if (grep(/^config_ops_bm_node/, @old_a)) {
|
||||
if (!grep(/^$script$/, @old_a)) {
|
||||
#not exact match, will replace it with new script
|
||||
for (@old_a) {
|
||||
s/^config_ops_bm_node.*$/$script/;
|
||||
}
|
||||
my $new_postboot = join(',', @old_a);
|
||||
$setup_hash{$node}={postbootscripts=>"$new_postboot"};
|
||||
}
|
||||
} else {
|
||||
if (! $found) {
|
||||
$setup_hash{$node}={postbootscripts=>"$post,$script"};
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (! $found) {
|
||||
$setup_hash{$node}={postbootscripts=>"$script"};
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$setup_hash{$node}={postbootscripts=>"$script"};
|
||||
}
|
||||
|
||||
if (keys(%setup_hash) > 0) {
|
||||
$posttab->setNodesAttribs(\%setup_hash);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------
|
||||
=head3 remove_postscript
|
||||
|
||||
It removes the 'config_ops_bm_node' postbootscript from
|
||||
the postscript table for the given node.
|
||||
|
||||
=cut
|
||||
#-------------------------------------------------------
|
||||
sub remove_postscript {
|
||||
my $callback=shift;
|
||||
my $node=shift;
|
||||
my $script=shift;
|
||||
|
||||
my $posttab=xCAT::Table->new("postscripts", -create =>1);
|
||||
my %setup_hash;
|
||||
my $ref = $posttab->getNodeAttribs($node,[qw(postscripts postbootscripts)]);
|
||||
my $found=0;
|
||||
if ($ref) {
|
||||
if (exists($ref->{postscripts})) {
|
||||
my @old_a = split(/,/, $ref->{postscripts});
|
||||
my @new_a = grep(!/^$script/, @old_a);
|
||||
if (scalar(@new_a) != scalar(@old_a)) {
|
||||
my $new_post = join(',', @new_a);
|
||||
$setup_hash{$node}={postscripts=>"$new_post"};
|
||||
}
|
||||
}
|
||||
|
||||
if (exists($ref->{postbootscripts})) {
|
||||
my @old_b = split(/,/, $ref->{postbootscripts});
|
||||
my @new_b = grep(!/^$script/, @old_b);
|
||||
if (scalar(@new_b) != scalar(@old_b)) {
|
||||
my $new_post = join(',', @new_b);
|
||||
$setup_hash{$node}={postbootscripts=>"$new_post"};
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (keys(%setup_hash) > 0) {
|
||||
$posttab->setNodesAttribs(\%setup_hash);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
=head3 opsaddbmnode_usage
|
||||
The usage text for opsaddbmnode command.
|
||||
=cut
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
sub opsaddbmnode_usage {
|
||||
my $cb=shift;
|
||||
my $rsp={};
|
||||
|
||||
$rsp->{data}->[0]= "Usage: opsaddbmnode -h";
|
||||
$rsp->{data}->[1]= " opsaddbmnode -v";
|
||||
$rsp->{data}->[2]= " opsaddbmnode <noderange> -s <service_host> [-V]";
|
||||
$cb->($rsp);
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
=head3 opsaddimage_usage
|
||||
The usage text for opsaddimage command.
|
||||
=cut
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
sub opsaddimage_usage {
|
||||
my $cb=shift;
|
||||
my $rsp={};
|
||||
|
||||
$rsp->{data}->[0]= "Usage: opsaddimage -h";
|
||||
$rsp->{data}->[1]= " opsaddimage -v";
|
||||
$rsp->{data}->[2]= " opsaddimage <image1,image2...> [-n <new_name1,new_name2...> -c <controller> [-V]";
|
||||
$cb->($rsp);
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
=head3 deploy_ops_bm_node_usage
|
||||
The usage text for deploy_ops_bm_node command.
|
||||
=cut
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
sub deploy_ops_bm_node_usage {
|
||||
my $cb=shift;
|
||||
my $rsp={};
|
||||
|
||||
$rsp->{data}->[0]= "Usage: deploy_ops_bm_node -h";
|
||||
$rsp->{data}->[1]= " deploy_ops_bm_node -v";
|
||||
$rsp->{data}->[2]= " deploy_ops_bm_node <node> --image <image_name> --host <ops_hostname> --ip <ops_fixed_ip> --mask <netmask>";
|
||||
$cb->($rsp);
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
=head3 cleanup_ops_bm_node_usage
|
||||
The usage text cleanup_ops_bm_node command.
|
||||
=cut
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
sub cleanup_ops_bm_node_usage {
|
||||
my $cb=shift;
|
||||
my $rsp={};
|
||||
|
||||
$rsp->{data}->[0]= "Usage: cleanup_ops_bm_node -h";
|
||||
$rsp->{data}->[1]= " cleanup_ops_bm_node -v";
|
||||
$rsp->{data}->[2]= " cleanup_ops_bm_node <node> [--ip <ops_fixed_ip>]";
|
||||
$cb->($rsp);
|
||||
}
|
||||
|
||||
1;
|
||||
@@ -1,17 +0,0 @@
|
||||
# Copyright (c) 2012 NTT DOCOMO, INC.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
from xcat.openstack.baremetal import driver
|
||||
|
||||
BareMetalDriver = driver.xCATBareMetalDriver
|
||||
@@ -1,256 +0,0 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
# coding=utf-8
|
||||
|
||||
"""
|
||||
A driver for Bare-metal platform.
|
||||
"""
|
||||
|
||||
from oslo.config import cfg
|
||||
|
||||
from nova.compute import power_state
|
||||
from nova import context as nova_context
|
||||
from nova import exception
|
||||
from nova.openstack.common import excutils
|
||||
from nova.openstack.common.gettextutils import _
|
||||
from nova.openstack.common import importutils
|
||||
from nova.openstack.common import jsonutils
|
||||
from nova.openstack.common import log as logging
|
||||
from nova.virt.baremetal import baremetal_states
|
||||
from nova.virt.baremetal import db
|
||||
from nova.virt.baremetal import driver as bm_driver
|
||||
from nova.virt.baremetal import utils as bm_utils
|
||||
from nova.virt import driver
|
||||
from nova.virt import firewall
|
||||
from nova.virt.libvirt import imagecache
|
||||
from xcat.openstack.baremetal import xcat_driver
|
||||
from xcat.openstack.baremetal import exception as xcat_exception
|
||||
from xcat.openstack.baremetal import power_states
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
CONF = cfg.CONF
|
||||
CONF.import_opt('use_ipv6', 'nova.netconf')
|
||||
|
||||
|
||||
class xCATBareMetalDriver(bm_driver.BareMetalDriver):
|
||||
"""BareMetal hypervisor driver."""
|
||||
|
||||
def __init__(self, virtapi, read_only=False):
|
||||
super(xCATBareMetalDriver, self).__init__(virtapi)
|
||||
self.xcat = xcat_driver.xCAT()
|
||||
|
||||
def _get_xCAT_image_name(self, image_meta):
|
||||
prop = image_meta.get('properties')
|
||||
xcat_image_name = prop.get('xcat_image_name')
|
||||
if xcat_image_name:
|
||||
return xcat_image_name
|
||||
else:
|
||||
raise xcat_exception.xCATInvalidImageError(image=image_meta.get('name'))
|
||||
|
||||
def spawn(self, context, instance, image_meta, injected_files,
|
||||
admin_password, network_info=None, block_device_info=None):
|
||||
"""
|
||||
Create a new instance/VM/domain on the virtualization platform.
|
||||
|
||||
Once this successfully completes, the instance should be
|
||||
running (power_state.RUNNING).
|
||||
|
||||
If this fails, any partial instance should be completely
|
||||
cleaned up, and the virtualization platform should be in the state
|
||||
that it was before this call began.
|
||||
|
||||
:param context: security context
|
||||
:param instance: Instance object as returned by DB layer.
|
||||
This function should use the data there to guide
|
||||
the creation of the new instance.
|
||||
:param image_meta: image object returned by nova.image.glance that
|
||||
defines the image from which to boot this instance
|
||||
:param injected_files: User files to inject into instance.
|
||||
:param admin_password: Administrator password to set in instance.
|
||||
:param network_info:
|
||||
:py:meth:`~nova.network.manager.NetworkManager.get_instance_nw_info`
|
||||
:param block_device_info: Information about block devices to be
|
||||
attached to the instance.
|
||||
"""
|
||||
#import pdb
|
||||
#pdb.set_trace()
|
||||
node_uuid = self._require_node(instance)
|
||||
node = db.bm_node_associate_and_update(context, node_uuid,
|
||||
{'instance_uuid': instance['uuid'],
|
||||
'instance_name': instance['hostname'],
|
||||
'task_state': baremetal_states.BUILDING})
|
||||
|
||||
try:
|
||||
self._plug_vifs(instance, network_info, context=context)
|
||||
self._attach_block_devices(instance, block_device_info)
|
||||
self._start_firewall(instance, network_info)
|
||||
|
||||
macs = self.macs_for_instance(instance)
|
||||
nodename = self.xcat.get_xcat_node_name(macs)
|
||||
imagename = self._get_xCAT_image_name(image_meta)
|
||||
hostname = instance.get('hostname')
|
||||
|
||||
#get the network information for the new node
|
||||
interfaces = bm_utils.map_network_interfaces(network_info, CONF.use_ipv6)
|
||||
if CONF.use_ipv6:
|
||||
fixed_ip = interfaces[0].get('address_v6')
|
||||
netmask = interfaces[0].get('netmask_v6')
|
||||
gateway = interfaces[0].get('gateway_v6')
|
||||
else:
|
||||
fixed_ip = interfaces[0].get('address')
|
||||
netmask = interfaces[0].get('netmask')
|
||||
gateway = interfaces[0].get('gateway')
|
||||
#convert netmask from IPAddress to unicode string
|
||||
if netmask:
|
||||
netmask = unicode(netmask)
|
||||
|
||||
#let xCAT install it
|
||||
bm_driver._update_state(context, node, instance, baremetal_states.DEPLOYING)
|
||||
self.xcat.deploy_node(nodename, imagename, hostname, fixed_ip, netmask, gateway)
|
||||
bm_driver._update_state(context, node, instance, baremetal_states.ACTIVE)
|
||||
except Exception as e:
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.error(_("Error occured while deploying instance %(instance)s "
|
||||
"on baremetal node %(node)s: %(error)s") %
|
||||
{'instance': instance['uuid'],
|
||||
'node': node['uuid'],
|
||||
'error':str(e)})
|
||||
bm_driver._update_state(context, node, instance, baremetal_states.ERROR)
|
||||
|
||||
def reboot(self, context, instance, network_info, reboot_type,
|
||||
block_device_info=None, bad_volumes_callback=None):
|
||||
"""Reboot the specified instance.
|
||||
|
||||
After this is called successfully, the instance's state
|
||||
goes back to power_state.RUNNING. The virtualization
|
||||
platform should ensure that the reboot action has completed
|
||||
successfully even in cases in which the underlying domain/vm
|
||||
is paused or halted/stopped.
|
||||
|
||||
:param instance: Instance object as returned by DB layer.
|
||||
:param network_info:
|
||||
:py:meth:`~nova.network.manager.NetworkManager.get_instance_nw_info`
|
||||
:param reboot_type: Either a HARD or SOFT reboot
|
||||
:param block_device_info: Info pertaining to attached volumes
|
||||
:param bad_volumes_callback: Function to handle any bad volumes
|
||||
encountered
|
||||
"""
|
||||
try:
|
||||
node = bm_driver._get_baremetal_node_by_instance_uuid(instance['uuid'])
|
||||
macs = self.macs_for_instance(instance)
|
||||
nodename = self.xcat.get_xcat_node_name(macs)
|
||||
self.xcat.reboot_node(nodename)
|
||||
bm_driver._update_state(context, node, instance, baremetal_states.RUNNING)
|
||||
except xcat_exception.xCATCommandError as e:
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.error(_("Error occured while rebooting instance %(instance)s "
|
||||
"on baremetal node %(node)s: %(error)s") %
|
||||
{'instance': instance['uuid'],
|
||||
'node': node['uuid'],
|
||||
'error':str(e)})
|
||||
bm_driver._update_state(context, node, instance, baremetal_states.ERROR)
|
||||
|
||||
def destroy(self, instance, network_info, block_device_info=None,
|
||||
context=None):
|
||||
"""Destroy (shutdown and delete) the specified instance.
|
||||
|
||||
If the instance is not found (for example if networking failed), this
|
||||
function should still succeed. It's probably a good idea to log a
|
||||
warning in that case.
|
||||
|
||||
:param context: security context
|
||||
:param instance: Instance object as returned by DB layer.
|
||||
:param network_info:
|
||||
:py:meth:`~nova.network.manager.NetworkManager.get_instance_nw_info`
|
||||
:param block_device_info: Information about block devices that should
|
||||
be detached from the instance.
|
||||
:param destroy_disks: Indicates if disks should be destroyed
|
||||
"""
|
||||
#import pdb
|
||||
#pdb.set_trace()
|
||||
context = nova_context.get_admin_context()
|
||||
try:
|
||||
node = bm_driver._get_baremetal_node_by_instance_uuid(instance['uuid'])
|
||||
|
||||
except exception.InstanceNotFound:
|
||||
LOG.warning(_("Destroy function called on a non-existing instance %s")
|
||||
% instance['uuid'])
|
||||
return
|
||||
|
||||
try:
|
||||
macs = self.macs_for_instance(instance)
|
||||
nodename = self.xcat.get_xcat_node_name(macs)
|
||||
interfaces = bm_utils.map_network_interfaces(network_info, CONF.use_ipv6)
|
||||
fixed_ip=None
|
||||
if interfaces and interfaces[0]:
|
||||
if CONF.use_ipv6:
|
||||
fixed_ip = interfaces[0].get('address_v6')
|
||||
else:
|
||||
fixed_ip = interfaces[0].get('address')
|
||||
if fixed_ip:
|
||||
self.xcat.cleanup_node(nodename, fixed_ip)
|
||||
else:
|
||||
self.xcat.cleanup_node(nodename)
|
||||
except Exception as e:
|
||||
#just log it and move on
|
||||
LOG.warning(_("Destroy called with xCAT error:" + str(e)))
|
||||
|
||||
try:
|
||||
self._detach_block_devices(instance, block_device_info)
|
||||
self._stop_firewall(instance, network_info)
|
||||
self._unplug_vifs(instance, network_info)
|
||||
|
||||
bm_driver._update_state(context, node, None, baremetal_states.DELETED)
|
||||
except Exception as e:
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.error(_("Error occurred while destroying instance %s: %s")
|
||||
% (instance['uuid'], str(e)))
|
||||
bm_driver._update_state(context, node, instance,
|
||||
baremetal_states.ERROR)
|
||||
|
||||
def power_off(self, instance, node=None):
|
||||
"""Power off the specified instance."""
|
||||
macs = self.macs_for_instance(instance)
|
||||
nodename = self.xcat.get_xcat_node_name(macs)
|
||||
self.xcat.power_off_node(nodename)
|
||||
|
||||
|
||||
def power_on(self, context, instance, network_info, block_device_info=None,
|
||||
node=None):
|
||||
"""Power on the specified instance."""
|
||||
macs = self.macs_for_instance(instance)
|
||||
nodename = self.xcat.get_xcat_node_name(macs)
|
||||
self.xcat.power_on_node(nodename)
|
||||
|
||||
|
||||
def get_console_output(self, instance):
|
||||
pass
|
||||
|
||||
def get_info(self, instance):
|
||||
"""Get the current status of an instance, by name (not ID!)
|
||||
|
||||
Returns a dict containing:
|
||||
:state: the running state, one of the power_state codes
|
||||
:max_mem: (int) the maximum memory in KBytes allowed
|
||||
:mem: (int) the memory in KBytes used by the domain
|
||||
:num_cpu: (int) the number of virtual CPUs for the domain
|
||||
:cpu_time: (int) the CPU time used in nanoseconds
|
||||
"""
|
||||
|
||||
node = bm_driver._get_baremetal_node_by_instance_uuid(instance['uuid'])
|
||||
macs = self.macs_for_instance(instance)
|
||||
nodename = self.xcat.get_xcat_node_name(macs)
|
||||
|
||||
ps = self.xcat.get_node_power_state(nodename)
|
||||
if ps == power_states.ON:
|
||||
pstate = power_state.RUNNING
|
||||
elif ps == power_states.OFF:
|
||||
pstate = power_state.SHUTDOWN
|
||||
else:
|
||||
pstate = power_state.NOSTATE
|
||||
|
||||
return {'state': pstate,
|
||||
'max_mem': node['memory_mb'],
|
||||
'mem': node['memory_mb'],
|
||||
'num_cpu': node['cpus'],
|
||||
'cpu_time': 0}
|
||||
@@ -1,41 +0,0 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
"""xCAT baremtal exceptions.
|
||||
"""
|
||||
|
||||
import functools
|
||||
import sys
|
||||
|
||||
from oslo.config import cfg
|
||||
import webob.exc
|
||||
|
||||
from nova.openstack.common import excutils
|
||||
from nova.openstack.common.gettextutils import _
|
||||
from nova.openstack.common import log as logging
|
||||
from nova import safe_utils
|
||||
from nova import exception as nova_exception
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
class xCATException(Exception):
|
||||
errmsg = _("xCAT general exception")
|
||||
|
||||
def __init__(self, errmsg=None, **kwargs):
|
||||
if not errmsg:
|
||||
errmsg = self.errmsg
|
||||
errmsg = errmsg % kwargs
|
||||
|
||||
super(xCATException, self).__init__(errmsg)
|
||||
|
||||
class xCATCommandError(xCATException):
|
||||
errmsg = _("Error returned when calling xCAT command %(cmd)s"
|
||||
" for node %(node)s:%(error)s")
|
||||
|
||||
class xCATInvalidImageError(xCATException):
|
||||
errmsg = _("The image %(image)s is not an xCAT image")
|
||||
|
||||
class xCATDeploymentFailure(xCATException):
|
||||
errmsg = _("xCAT node deployment failed for node %(node)s:%(error)s")
|
||||
|
||||
class xCATRebootFailure(xCATException):
|
||||
errmsg = _("xCAT node rebooting failed for node %(node)s:%(error)s")
|
||||
@@ -1,9 +0,0 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
"""
|
||||
Possible xCAT node power states.
|
||||
"""
|
||||
|
||||
OFF = 'off'
|
||||
ON = 'on'
|
||||
ERROR = 'error'
|
||||
@@ -1,260 +0,0 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
# coding=utf-8
|
||||
|
||||
|
||||
"""
|
||||
Baremetal xCAT power manager.
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import stat
|
||||
from oslo.config import cfg
|
||||
import datetime
|
||||
|
||||
from nova import context as nova_context
|
||||
from nova.virt.baremetal import baremetal_states
|
||||
from nova.openstack.common.gettextutils import _
|
||||
from nova.openstack.common import log as logging
|
||||
from nova.openstack.common import loopingcall
|
||||
from nova.openstack.common import timeutils
|
||||
from nova import paths
|
||||
from nova import utils
|
||||
from xcat.openstack.baremetal import exception
|
||||
from xcat.openstack.baremetal import power_states
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
# register configuration options
|
||||
xcat_opts = [
|
||||
cfg.IntOpt('deploy_timeout',
|
||||
help='Timeout for node deployment. Default: 0 second (unlimited)',
|
||||
default=0),
|
||||
cfg.IntOpt('reboot_timeout',
|
||||
help='Timeout for rebooting a node. Default: 0 second (unlimited)',
|
||||
default=0),
|
||||
cfg.IntOpt('deploy_checking_interval',
|
||||
help='Checking interval for node deployment. Default: 10 seconds',
|
||||
default=10),
|
||||
cfg.IntOpt('reboot_checking_interval',
|
||||
help='Checking interval for rebooting a node. Default: 5 seconds',
|
||||
default=5),
|
||||
]
|
||||
xcat_group = cfg.OptGroup(name='xcat',
|
||||
title='xCAT Options')
|
||||
CONF = cfg.CONF
|
||||
CONF.register_group(xcat_group)
|
||||
CONF.register_opts(xcat_opts, xcat_group)
|
||||
|
||||
|
||||
class xCAT(object):
|
||||
"""A driver that calls xCAT funcions"""
|
||||
|
||||
def __init__(self):
|
||||
#setup the path for xCAT commands
|
||||
#xcatroot = os.getenv('XCATROOT', '/opt/xcat/')
|
||||
#sys.path.append("%s/bin" % xcatroot)
|
||||
#sys.path.append("%s/sbin" % xcatroot)
|
||||
pass
|
||||
|
||||
def _exec_xcat_command(self, command):
|
||||
"""Calls xCAT command."""
|
||||
args = command.split(" ")
|
||||
out, err = utils.execute(*args, run_as_root=True)
|
||||
LOG.debug(_("xCAT command stdout: '%(out)s', stderr: '%(err)s'"),
|
||||
{'out': out, 'err': err})
|
||||
return out, err
|
||||
|
||||
def get_xcat_node_name(self, macs):
|
||||
"""Get the xcat node name given mac addressed.
|
||||
|
||||
It uses the mac address to search for the node name in xCAT.
|
||||
"""
|
||||
for mac in macs:
|
||||
out, err = self._exec_xcat_command("lsdef -w mac=%s" % mac)
|
||||
if out:
|
||||
return out.split(" ")[0]
|
||||
|
||||
errstr='No node found in xCAT with the following mac address: ' \
|
||||
+ ','.join(macs)
|
||||
LOG.warning(errstr)
|
||||
raise exception.xCATCommandError(errstr)
|
||||
|
||||
|
||||
def deploy_node(self, nodename, imagename, hostname, fixed_ip, netmask, gateway):
|
||||
"""
|
||||
Install the node.
|
||||
|
||||
It calls xCAT command deploy_ops_bmnode which prepares the node
|
||||
by adding the config_ops_bm_node postbootscript to the postscript
|
||||
table for the node, then call nodeset and then boot the node up.
|
||||
"""
|
||||
out, err = self._exec_xcat_command(
|
||||
"deploy_ops_bm_node %(node)s --image %(image)s"
|
||||
" --host %(host)s --ip %(ip)s --mask %(mask)s"
|
||||
% {'node': nodename,
|
||||
'image': imagename,
|
||||
'host': hostname,
|
||||
'ip': fixed_ip,
|
||||
'mask': netmask,
|
||||
})
|
||||
if err:
|
||||
errstr = _("Error returned when calling xCAT deploy_ops_bm_node"
|
||||
" command for node %s:%s") % (nodename, err)
|
||||
LOG.warning(errstr)
|
||||
raise exception.xCATCommandError(errstr)
|
||||
self._wait_for_node_deploy(nodename)
|
||||
|
||||
def cleanup_node(self, nodename, fixed_ip=None):
|
||||
"""
|
||||
Undo all the changes made to the node by deploy_node function.
|
||||
|
||||
It calls xCAT command cleanup_ops_bm_node which removes the
|
||||
config_ops_bm_node postbootscript from the postscript table
|
||||
for the node, removes the alias ip and then power the node off.
|
||||
"""
|
||||
cmd = "cleanup_ops_bm_node %s" % nodename
|
||||
if fixed_ip:
|
||||
cmd += " --ip %s" % fixed_ip
|
||||
out, err = self._exec_xcat_command(cmd)
|
||||
|
||||
if err:
|
||||
errstr = _("Error returned when calling xCAT cleanup_ops_bm_node"
|
||||
" command for node %s:%s") % (nodename, err)
|
||||
LOG.warning(errstr)
|
||||
raise exception.xCATCommandError(errstr)
|
||||
|
||||
def power_on_node(self, nodename):
|
||||
"""Power on the node."""
|
||||
state = self.get_node_power_state(nodename)
|
||||
if state == power_states.ON:
|
||||
LOG.warning(_("Powring on node called, but the node %s "
|
||||
"is already on") % nodename)
|
||||
out, err = self._exec_xcat_command("rpower %s on" % nodename)
|
||||
if err:
|
||||
errstr = _("Error returned when calling xCAT rpower on"
|
||||
" for node %s:%s") % (nodename, err)
|
||||
LOG.warning(errstr)
|
||||
raise exception.xCATCommandError(errstr)
|
||||
else:
|
||||
self._wait_for_node_reboot(nodename)
|
||||
return power_states.ON
|
||||
|
||||
def power_off_node(self, nodename):
|
||||
"""Power off the node."""
|
||||
state = self.get_node_power_state(nodename)
|
||||
if state == power_states.OFF:
|
||||
LOG.warning(_("Powring off node called, but the node %s "
|
||||
"is already off") % nodename)
|
||||
out, err = self._exec_xcat_command("rpower %s off" % nodename)
|
||||
if err:
|
||||
errstr = _("Error returned when calling xCAT rpower off"
|
||||
" for node %s:%s") % (nodename, err)
|
||||
LOG.warning(errstr)
|
||||
raise exception.xCATCommandError(errstr)
|
||||
else:
|
||||
return power_states.OFF
|
||||
|
||||
def reboot_node(self, nodename):
|
||||
"""Reboot the node."""
|
||||
out, err = self._exec_xcat_command("rpower %s boot" % nodename)
|
||||
if err:
|
||||
errstr = _("Error returned when calling xCAT rpower boot"
|
||||
" for node %s:%s") % (nodename, err)
|
||||
LOG.warning(errstr)
|
||||
raise exception.xCATCommandError(errstr)
|
||||
|
||||
self._wait_for_node_reboot(nodename)
|
||||
return power_states.ON
|
||||
|
||||
|
||||
def get_node_power_state(self, nodename):
|
||||
out, err = self._exec_xcat_command("rpower %s stat" % nodename)
|
||||
if err:
|
||||
errstr = _("Error returned when calling xCAT rpower stat"
|
||||
" for node %s:%s") % (nodename, err)
|
||||
LOG.warning(errstr)
|
||||
raise exception.xCATCommandError(errstr)
|
||||
else:
|
||||
state = out.split(":")[1]
|
||||
if state:
|
||||
state = state.strip()
|
||||
if state == 'on':
|
||||
return power_states.ON
|
||||
elif state == 'off':
|
||||
return power_states.OFF
|
||||
|
||||
return power_states.ERROR
|
||||
|
||||
def _wait_for_node_deploy(self, nodename):
|
||||
"""Wait for xCAT node deployment to complete."""
|
||||
locals = {'errstr':''}
|
||||
|
||||
def _wait_for_deploy():
|
||||
out,err = self._exec_xcat_command("nodels %s nodelist.status" % nodename)
|
||||
if err:
|
||||
locals['errstr'] = _("Error returned when quering node status"
|
||||
" for node %s:%s") % (nodename, err)
|
||||
LOG.warning(locals['errstr'])
|
||||
raise loopingcall.LoopingCallDone()
|
||||
|
||||
if out:
|
||||
node,status = out.split(": ")
|
||||
status = status.strip()
|
||||
if status == "booted":
|
||||
LOG.info(_("Deployment for node %s completed.")
|
||||
% nodename)
|
||||
raise loopingcall.LoopingCallDone()
|
||||
|
||||
if (CONF.xcat.deploy_timeout and
|
||||
timeutils.utcnow() > expiration):
|
||||
locals['errstr'] = _("Timeout while waiting for"
|
||||
" deployment of node %s.") % nodename
|
||||
LOG.warning(locals['errstr'])
|
||||
raise loopingcall.LoopingCallDone()
|
||||
|
||||
expiration = timeutils.utcnow() + datetime.timedelta(
|
||||
seconds=CONF.xcat.deploy_timeout)
|
||||
timer = loopingcall.FixedIntervalLoopingCall(_wait_for_deploy)
|
||||
# default check every 10 seconds
|
||||
timer.start(interval=CONF.xcat.deploy_checking_interval).wait()
|
||||
|
||||
if locals['errstr']:
|
||||
raise exception.xCATDeploymentFailure(locals['errstr'])
|
||||
|
||||
|
||||
def _wait_for_node_reboot(self, nodename):
|
||||
"""Wait for xCAT node boot to complete."""
|
||||
locals = {'errstr':''}
|
||||
|
||||
def _wait_for_reboot():
|
||||
out,err = self._exec_xcat_command("nodestat %s" % nodename)
|
||||
if err:
|
||||
locals['errstr'] = _("Error returned when quering node status"
|
||||
" for node %s:%s") % (nodename, err)
|
||||
LOG.warning(locals['errstr'])
|
||||
raise loopingcall.LoopingCallDone()
|
||||
|
||||
if out:
|
||||
node,status = out.split(": ")
|
||||
status = status.strip()
|
||||
if status == "sshd":
|
||||
LOG.info(_("Rebooting node %s completed.")
|
||||
% nodename)
|
||||
raise loopingcall.LoopingCallDone()
|
||||
|
||||
if (CONF.xcat.reboot_timeout and
|
||||
timeutils.utcnow() > expiration):
|
||||
locals['errstr'] = _("Timeout while waiting for"
|
||||
" rebooting node %s.") % nodename
|
||||
LOG.warning(locals['errstr'])
|
||||
raise loopingcall.LoopingCallDone()
|
||||
|
||||
expiration = timeutils.utcnow() + datetime.timedelta(
|
||||
seconds=CONF.xcat.reboot_timeout)
|
||||
timer = loopingcall.FixedIntervalLoopingCall(_wait_for_reboot)
|
||||
# default check every 5 seconds
|
||||
timer.start(interval=CONF.xcat.reboot_checking_interval).wait()
|
||||
|
||||
if locals['errstr']:
|
||||
raise exception.xCATRebootFailure(locals['errstr'])
|
||||
@@ -1,92 +0,0 @@
|
||||
=head1 NAME
|
||||
|
||||
B<opsaddbmnode> - It adds xCAT baremetal nodes to an OpenStack cloud.
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
B<opsaddbmnode> I<noderange> B<-s> I<service_host> [B<-V>|B<--verbose>]
|
||||
|
||||
B<opsaddbmnode> [B<-h>|B<--help>]
|
||||
|
||||
B<opsaddbmnode> [B<-v>|B<--version>]
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
The B<opsaddbmnode> command registers xCAT nodes to an OpenStack cloud. An OpenStack nova baremetal node registration command takes several node attributes:
|
||||
|
||||
=over
|
||||
|
||||
=item BMC ip addresss, user id and password
|
||||
|
||||
=item Name of nova compute host which will control this baremetal node
|
||||
|
||||
=item Number of CPUs in the node
|
||||
|
||||
=item Memory in the node (MB)
|
||||
|
||||
=item Local hard disk in the node (GB)
|
||||
|
||||
=item MAC address to provision the node
|
||||
|
||||
=back
|
||||
|
||||
The opsaddbmnode command pulls the above baremetal node information from xCAT tables and calls "nova baremetal-node-create" to register the baremetal node with the OpenStack cloud.
|
||||
|
||||
Please make sure the following xCAT tables are filled with correct information for the given nodes before calling this command.
|
||||
|
||||
=over
|
||||
|
||||
=item ipmi (for BMC ip addresss, user id and password)
|
||||
|
||||
=item mac (for MAC address)
|
||||
|
||||
=item hwinv (for CPU, memory and disk info.)
|
||||
|
||||
=back
|
||||
|
||||
=head1 Parameters
|
||||
|
||||
I<noderage> is a comma separated node or node group names.
|
||||
|
||||
|
||||
=head1 OPTIONS
|
||||
|
||||
=over 10
|
||||
|
||||
=item B<-s> The node name of the OpenStack compute host that hosts the baremetal nodes.
|
||||
|
||||
=item B<-h|--help> Display usage message.
|
||||
|
||||
=item B<-v|--version> The Command Version.
|
||||
|
||||
=item B<-V|--verbose> Verbose output.
|
||||
|
||||
=back
|
||||
|
||||
=head1 RETURN VALUE
|
||||
|
||||
0 The command completed successfully.
|
||||
|
||||
1 An error has occurred.
|
||||
|
||||
=head1 EXAMPLES
|
||||
|
||||
=over 3
|
||||
|
||||
=item 1
|
||||
|
||||
To register node1, node2 and node3 to OpenStack, sv1 is the compute host.
|
||||
|
||||
opsassbmnode node1,node2,node3 -s sv1
|
||||
|
||||
|
||||
=back
|
||||
|
||||
=head1 FILES
|
||||
|
||||
/opt/xcat/bin/opadddbmnode
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<opsaddimage(1)|opsaddimage.1>
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
=head1 NAME
|
||||
|
||||
B<opsaddimage> - It adds or removes nodes for the vlan.
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
B<opsaddimage> I<image1,image2,...> B<-n> I<new_name1,new_name2,...> [B<-c> I<controller>] [B<-V>|B<--verbose>]
|
||||
|
||||
B<opsaddimage> [B<-h>|B<--help>]
|
||||
|
||||
B<opsaddimage> [B<-v>|B<--version>]
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
The B<opsaddimage> command adds a list of xCAT images into the OpenStack cloud.
|
||||
|
||||
Under the cover, it creates a fake image and registers the fake image into OpenStack with command B<glance image-create>. It sets the property in the image to indicate that this is an xCAT image and also stores the original xCAT image name in the property for further reference.
|
||||
|
||||
The xCAT image names can be listed using B<lsdef -t osimage> command.
|
||||
|
||||
=head1 Parameters
|
||||
|
||||
I<image1,image1...> a comma separated xCAT images names.
|
||||
|
||||
|
||||
=head1 OPTIONS
|
||||
|
||||
=over 10
|
||||
|
||||
=item B<-n> a comma separated new image names in the OpenStack. If omitted, the default is the original xCAT image nanme.
|
||||
|
||||
=item B<-c> the node name of the OpenStack controller. This node must be an xCAT managed node.
|
||||
|
||||
=item B<-h|--help> Display usage message.
|
||||
|
||||
=item B<-v|--version> The Command Version.
|
||||
|
||||
=item B<-V|--verbose> Verbose output.
|
||||
|
||||
=back
|
||||
|
||||
=head1 RETURN VALUE
|
||||
|
||||
0 The command completed successfully.
|
||||
|
||||
1 An error has occurred.
|
||||
|
||||
=head1 EXAMPLES
|
||||
|
||||
=over 3
|
||||
|
||||
=item 1.
|
||||
|
||||
To register xCAT image rhels6.3-x86_64-install-compute into OpenStack.
|
||||
|
||||
opsaddimage rhels6.3-x86_64-install-compute -c sv2
|
||||
|
||||
=back
|
||||
|
||||
=head1 FILES
|
||||
|
||||
/opt/xcat/bin/opsaddimage
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<opsaddbmnode(1)|opsaddbmnode.1>
|
||||
|
||||
@@ -1,215 +0,0 @@
|
||||
#!/bin/sh
|
||||
# IBM(c) 2014 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
|
||||
# xCAT post script for configuring the openstack baremetal node.
|
||||
# The format is:
|
||||
# config_ops_bm_node ops_hostname ops_ip ops_netmask
|
||||
|
||||
|
||||
get_os_type()
|
||||
{
|
||||
#get os type
|
||||
str_os_type=`uname | tr 'A-Z' 'a-z'`
|
||||
str_temp=''
|
||||
if [ "$str_os_type" = "linux" ];then
|
||||
str_temp=`echo $OSVER | grep -E '(sles|suse)'`
|
||||
if [ -f "/etc/debian_version" ];then
|
||||
str_os_type="debian"
|
||||
elif [ -f "/etc/SuSE-release" -o -n "$str_temp" ];then
|
||||
str_os_type="sles"
|
||||
else
|
||||
str_os_type="redhat"
|
||||
fi
|
||||
else
|
||||
str_os_type="aix"
|
||||
fi
|
||||
echo "$str_os_type"
|
||||
}
|
||||
|
||||
|
||||
setup_ip()
|
||||
{
|
||||
str_os_type=$1
|
||||
str_if_name=$2
|
||||
str_v4ip=$3
|
||||
str_v4mask=$4
|
||||
|
||||
ret=`ifconfig $str_if_name |grep "inet addr" 2>&1`
|
||||
if [ $? -eq 0 ]; then
|
||||
old_ip=`echo $ret|cut -d':' -f2 |cut -d' ' -f1`
|
||||
old_mask=`echo $ret|cut -d':' -f4`
|
||||
#echo "old ip = $old_ip, old mask=$old_mask"
|
||||
if [ "$old_ip" == "$str_v4ip" -a "$old_mask" == "$str_v4mask" ]; then
|
||||
#if nic is up and the address is the same, then donothing
|
||||
#echo "do nothing"
|
||||
exit 0
|
||||
else
|
||||
#bring down the nic and reconstruct it.
|
||||
#echo "bring down the old nic"
|
||||
ifconfig $str_if_name del $old_ip
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$str_os_type" = "sles" ];then
|
||||
str_conf_file="/etc/sysconfig/network/ifcfg-${str_if_name}"
|
||||
if [ -f $str_conf_file ]; then
|
||||
rm $str_conf_file
|
||||
fi
|
||||
echo "DEVICE=${str_if_name}" > $str_conf_file
|
||||
echo "BOOTPROTO=static" >> $str_conf_file
|
||||
echo "IPADDR=${str_v4ip}" >> $str_conf_file
|
||||
echo "NETMASK=${str_v4mask}" >> $str_conf_file
|
||||
echo "NETWORK=''" >> $str_conf_file
|
||||
echo "STARTMODE=onboot" >> $str_conf_file
|
||||
echo "USERCONTROL=no" >> $str_conf_file
|
||||
ifup $str_if_name
|
||||
#debian ubuntu
|
||||
elif [ "$str_os_type" = "debian" ];then
|
||||
str_conf_file="/etc/network/interfaces.d/${str_if_name}"
|
||||
if [ -f $str_conf_file ]; then
|
||||
rm $str_conf_file
|
||||
fi
|
||||
echo "auto ${str_if_name}" > $str_conf_file
|
||||
echo "iface ${str_if_name} inet static" >> $str_conf_file
|
||||
echo " address ${str_v4ip}" >> $str_conf_file
|
||||
echo " netmask ${str_v4mask}" >> $str_conf_file
|
||||
ifconfig $str_if_name up
|
||||
else
|
||||
# Write the info to the ifcfg file for redhat
|
||||
str_conf_file="/etc/sysconfig/network-scripts/ifcfg-${str_if_name}"
|
||||
if [ -f $str_conf_file ]; then
|
||||
rm $str_conf_file
|
||||
fi
|
||||
echo "DEVICE=${str_if_name}" > $str_conf_file
|
||||
echo "BOOTPROTO=static" >> $str_conf_file
|
||||
echo "NM_CONTROLLED=no" >> $str_conf_file
|
||||
echo "IPADDR=${str_v4ip}" >> $str_conf_file
|
||||
echo "NETMASK=${str_v4mask}" >> $str_conf_file
|
||||
echo "ONBOOT=yes" >> $str_conf_file
|
||||
ifup $str_if_name
|
||||
fi
|
||||
}
|
||||
|
||||
#change hostname permanently
|
||||
change_host_name()
|
||||
{
|
||||
str_os_type=$1
|
||||
str_hostname=$2
|
||||
|
||||
hostname $str_hostname
|
||||
|
||||
if [ "$str_os_type" = "sles" ];then
|
||||
echo "Persistently changing the hostname not implemented yet."
|
||||
#debian ubuntu and rh7
|
||||
elif [ -f "/etc/hostname" ];then
|
||||
conf_file="/etc/hostname"
|
||||
echo "$str_hostname" > $conf_file
|
||||
else
|
||||
conf_file="/etc/sysconfig/network"
|
||||
if [ ! -f $conf_file ]; then
|
||||
touch $conf_file
|
||||
fi
|
||||
grep 'HOSTNAME' $conf_file 2>&1 > /dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
sed -i "s/HOSTNAME=.*/HOSTNAME=$str_hostname/" $conf_file
|
||||
else
|
||||
echo "HOSTNAME=$str_hostname" >> $conf_file
|
||||
fi
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
str_os_type=$(get_os_type)
|
||||
echo "os_type=$str_os_type"
|
||||
if [ "$str_os_type" = "aix" ]; then
|
||||
logger -t xcat "config_ops_bm_node dose not support AIX."
|
||||
echo "config_ops_bm_node dose not support AIX."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
#change the hostname
|
||||
if [[ -n "$1" ]]; then
|
||||
change_host_name $str_os_type $1
|
||||
fi
|
||||
|
||||
#Add the openstack ip to the node
|
||||
if [[ -n $2 ]]; then
|
||||
ops_ip=$2
|
||||
|
||||
if [[ -z $3 ]]; then
|
||||
logger -t xcat "config_ops_bm_node: Please specify the netmask."
|
||||
echo "config_ops_bm_node: Please specify the netmask."
|
||||
exit 1
|
||||
else
|
||||
ops_mask=$3
|
||||
fi
|
||||
|
||||
#figure out the install nic
|
||||
if [[ -n $MACADDRESS ]]; then
|
||||
pos=0
|
||||
#mac has the following format: 01:02:03:04:05:0E!node5|01:02:03:05:0F!node6-eth1
|
||||
for x in `echo "$MACADDRESS" | tr "|" "\n"`
|
||||
do
|
||||
node=""
|
||||
mac=""
|
||||
pos=$((pos+1))
|
||||
i=`expr index $x !`
|
||||
if [[ $i -gt 0 ]]; then
|
||||
node=`echo ${x##*!}`
|
||||
mac_tmp=`echo ${x%%!*}`
|
||||
else
|
||||
mac_tmp=$x
|
||||
fi
|
||||
|
||||
if [[ $pos -eq 1 ]]; then
|
||||
mac1=$mac_tmp
|
||||
fi
|
||||
|
||||
if [[ "$PRIMARYNIC" = "$mac_tmp" ]]; then
|
||||
mac=$mac_tmp
|
||||
break
|
||||
fi
|
||||
|
||||
if [[ -z "$PRIMARYNIC" ]] || [[ "$PRIMARYNIC" = "mac" ]]; then
|
||||
if [[ -z $node ]] || [[ "$node" = "$NODE" ]]; then
|
||||
mac=$mac_tmp
|
||||
break
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ -z $mac ]]; then
|
||||
if [[ -z "$PRIMARYNIC" ]] || [[ "$PRIMARYNIC" = "mac" ]]; then
|
||||
mac=$mac1 #if nothing mathes, take the first mac
|
||||
else
|
||||
nic=$PRIMARYNIC #or the primary nic itself is the nic
|
||||
fi
|
||||
fi
|
||||
else
|
||||
logger -t xcat "config_ops_bm_node: no mac addresses are defined in the mac table for the node $NODE"
|
||||
echo "config_ops_bm_node: no mac addresses are defined in the mac table for the node $NODE"
|
||||
index=$((index+1))
|
||||
continue
|
||||
fi
|
||||
echo "mac=$mac"
|
||||
|
||||
#find the nic that has the mac
|
||||
if [[ -z $nic ]]; then
|
||||
#go to each nic to match the mac address
|
||||
ret=`ifconfig |grep -i $mac 2>&1`;
|
||||
if [ $? -eq 0 ]; then
|
||||
nic=`echo $ret |head -n1|cut -d' ' -f 1`
|
||||
else
|
||||
logger -t xcat "config_ops_bm_node: The mac address for the network for $NODE is not defined."
|
||||
echo "config_ops_bm_node: The mac address for the network for $NODE is not defined."
|
||||
fi
|
||||
fi
|
||||
echo "nic=$nic"
|
||||
|
||||
#now setup the ip alias
|
||||
setup_ip $str_os_type $nic:0 $ops_ip $ops_mask
|
||||
fi
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,94 +0,0 @@
|
||||
#!/bin/sh
|
||||
# IBM(c) 2014 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
|
||||
# xCAT post script for deconfiguring the openstack baremetal node.
|
||||
# The format is:
|
||||
# deconfig_ops_bm_node ops_ip
|
||||
|
||||
|
||||
get_os_type()
|
||||
{
|
||||
#get os type
|
||||
str_os_type=`uname | tr 'A-Z' 'a-z'`
|
||||
str_temp=''
|
||||
if [ "$str_os_type" = "linux" ];then
|
||||
str_temp=`echo $OSVER | grep -E '(sles|suse)'`
|
||||
if [ -f "/etc/debian_version" ];then
|
||||
str_os_type="debian"
|
||||
elif [ -f "/etc/SuSE-release" -o -n "$str_temp" ];then
|
||||
str_os_type="sles"
|
||||
else
|
||||
str_os_type="redhat"
|
||||
fi
|
||||
else
|
||||
str_os_type="aix"
|
||||
fi
|
||||
echo "$str_os_type"
|
||||
}
|
||||
|
||||
#change hostname permanently
|
||||
change_host_name()
|
||||
{
|
||||
str_os_type=$1
|
||||
str_hostname=$2
|
||||
|
||||
hostname $str_hostname
|
||||
|
||||
if [ "$str_os_type" = "sles" ];then
|
||||
echo "Persistently changing the hostname not implemented yet."
|
||||
#debian ubuntu and rh7
|
||||
elif [ -f "/etc/hostname" ];then
|
||||
conf_file="/etc/hostname"
|
||||
echo "$str_hostname" > $conf_file
|
||||
else
|
||||
conf_file="/etc/sysconfig/network"
|
||||
if [ ! -f $conf_file ]; then
|
||||
touch $conf_file
|
||||
fi
|
||||
grep 'HOSTNAME' $conf_file 2>&1 > /dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
sed -i "s/HOSTNAME=.*/HOSTNAME=$str_hostname/" $conf_file
|
||||
else
|
||||
echo "HOSTNAME=$str_hostname" >> $conf_file
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
str_os_type=$(get_os_type)
|
||||
echo "os_type=$str_os_type"
|
||||
|
||||
if [ $str_os_type == "aix" ]; then
|
||||
logger -t xcat "deconfig_ops_bm_node dose not support AIX."
|
||||
echo "deconfig_ops_bm_node dose not support AIX."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
#change the hostname
|
||||
#hostname $NODE
|
||||
change_host_name $str_os_type $NODE
|
||||
|
||||
#remove the openstack ip from the node
|
||||
if [[ -n $1 ]]; then
|
||||
ops_ip=$1
|
||||
nic=$(ip addr | grep $ops_ip | awk '{print $NF}')
|
||||
echo "nic=$nic, ops_ip=$ops_ip"
|
||||
|
||||
ifconfig $nic del $ops_ip
|
||||
|
||||
#delete the configuration file
|
||||
if [ "$str_os_type" = "sles" ]; then
|
||||
str_conf_file="/etc/sysconfig/network/ifcfg-$nic"
|
||||
elif [ "$str_os_type" = "debian" ]; then #debian ubuntu
|
||||
str_conf_file="/etc/network/interfaces.d/$nic"
|
||||
else #redhat
|
||||
str_conf_file="/etc/sysconfig/network-scripts/ifcfg-$nic"
|
||||
fi
|
||||
if [ -f $str_conf_file ]; then
|
||||
rm $str_conf_file
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,102 +0,0 @@
|
||||
Summary: Executables and data of the xCAT baremetal driver for OpenStack
|
||||
Name: xCAT-OpenStack-baremetal
|
||||
Version: %(cat Version)
|
||||
Release: snap%(date +"%Y%m%d%H%M")
|
||||
Epoch: 4
|
||||
License: IBM
|
||||
Group: Applications/System
|
||||
Source: xCAT-OpenStack-baremetal-%{version}.tar.gz
|
||||
Packager: IBM Corp.
|
||||
Vendor: IBM Corp.
|
||||
Distribution: %{?_distribution:%{_distribution}}%{!?_distribution:%{_vendor}}
|
||||
Prefix: /opt/xcat
|
||||
BuildRoot: /var/tmp/%{name}-%{version}-%{release}-root
|
||||
|
||||
%ifos linux
|
||||
BuildArch: noarch
|
||||
%endif
|
||||
|
||||
|
||||
Provides: xCAT-OpenStack-baremetal = %{epoch}:%{version}
|
||||
|
||||
Requires: xCAT-client
|
||||
|
||||
%description
|
||||
xCAT-OpenStack-baremetal provides the baremetal driver for OpenStack.
|
||||
|
||||
%prep
|
||||
%setup -q -n xCAT-OpenStack-baremetal
|
||||
%build
|
||||
|
||||
# Convert pods to man pages and html pages
|
||||
./xpod2man
|
||||
|
||||
%install
|
||||
# The install phase puts all of the files in the paths they should be in when the rpm is
|
||||
# installed on a system. The RPM_BUILD_ROOT is a simulated root file system and usually
|
||||
# has a value like: /var/tmp/xCAT-OpenStack-baremetal-2.0-snap200802270932-root
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
mkdir -p $RPM_BUILD_ROOT/%{prefix}/bin
|
||||
mkdir -p $RPM_BUILD_ROOT/%{prefix}/sbin
|
||||
mkdir -p $RPM_BUILD_ROOT/%{prefix}/lib/perl/xCAT_plugin
|
||||
mkdir -p $RPM_BUILD_ROOT/%{prefix}/lib/python/xcat/openstack/baremetal
|
||||
mkdir -p $RPM_BUILD_ROOT/%{prefix}/share/xcat/openstack/postscripts
|
||||
mkdir -p $RPM_BUILD_ROOT/%{prefix}/share/man/man1
|
||||
mkdir -p $RPM_BUILD_ROOT/%{prefix}/share/doc/man1
|
||||
|
||||
|
||||
set +x
|
||||
|
||||
cp -R lib/* $RPM_BUILD_ROOT/%{prefix}/lib
|
||||
cp share/xcat/openstack/postscripts/* $RPM_BUILD_ROOT/%{prefix}/share/xcat/openstack/postscripts
|
||||
|
||||
|
||||
# These were built dynamically in the build phase
|
||||
cp share/man/man1/* $RPM_BUILD_ROOT/%{prefix}/share/man/man1
|
||||
chmod 444 $RPM_BUILD_ROOT/%{prefix}/share/man/man1/*
|
||||
|
||||
# These were built dynamically during the build phase
|
||||
cp share/doc/man1/* $RPM_BUILD_ROOT/%{prefix}/share/doc/man1
|
||||
chmod 644 $RPM_BUILD_ROOT/%{prefix}/share/doc/man1/*
|
||||
|
||||
# These links get made in the RPM_BUILD_ROOT/prefix area
|
||||
ln -sf ../bin/xcatclient $RPM_BUILD_ROOT/%{prefix}/sbin/deploy_ops_bm_node
|
||||
ln -sf ../bin/xcatclient $RPM_BUILD_ROOT/%{prefix}/sbin/cleanup_ops_bm_node
|
||||
ln -sf ../bin/xcatclient $RPM_BUILD_ROOT/%{prefix}/bin/opsaddbmnode
|
||||
ln -sf ../bin/xcatclientnnr $RPM_BUILD_ROOT/%{prefix}/bin/opsaddimage
|
||||
|
||||
set -x
|
||||
|
||||
|
||||
%clean
|
||||
# This step does not happen until *after* the %files packaging below
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
%files
|
||||
%defattr(-,root,root)
|
||||
#%doc LICENSE.html
|
||||
# Just package everything that has been copied into RPM_BUILD_ROOT
|
||||
%{prefix}
|
||||
|
||||
|
||||
%changelog
|
||||
|
||||
%post
|
||||
#copy the postscripts under /installl/postscripts directory on MN only
|
||||
if [ -f "/etc/xCATMN" ]; then
|
||||
cp $RPM_INSTALL_PREFIX0/share/xcat/openstack/postscripts/* /install/postscripts/
|
||||
fi
|
||||
|
||||
%preun
|
||||
#remove postscripts under /installl/postscripts directory on MN only
|
||||
if [ -f "/etc/xCATMN" ]; then
|
||||
for fn in $RPM_INSTALL_PREFIX0/share/xcat/openstack/postscripts/*
|
||||
do
|
||||
bn=`basename $fn`
|
||||
rm /install/postscripts/$bn
|
||||
done
|
||||
fi
|
||||
exit 0
|
||||
|
||||
|
||||
@@ -1,214 +0,0 @@
|
||||
#!/usr/bin/perl
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
|
||||
# First builds the xCAT summary man page from Synopsis of each man page.
|
||||
# Then converts all of the pod man pages into html (including links to each other)
|
||||
|
||||
# We assume that this script is run in the xCAT-vlan-2.0 dir, so everything is
|
||||
# done relative to that.
|
||||
|
||||
use strict;
|
||||
#use lib '.';
|
||||
use Pod::Man;
|
||||
use Pod::Html;
|
||||
|
||||
my $poddir = 'pods';
|
||||
my $mandir = 'share/man';
|
||||
my $htmldir = 'share/doc';
|
||||
my $cachedir = '/tmp';
|
||||
|
||||
my @pods = getPodList($poddir);
|
||||
#foreach (@pods) { print "$_\n"; } exit;
|
||||
|
||||
# Build the cmd overview page.
|
||||
#writesummarypage("$poddir/man1/xcat.1.pod", @pods);
|
||||
|
||||
# Build the man page for each pod.
|
||||
#mkdir($mandir) or die "Error: could not create $mandir.\n";
|
||||
print "Converting PODs to man pages...\n";
|
||||
foreach my $podfile (@pods) {
|
||||
my $manfile = $podfile;
|
||||
$manfile =~ s/^$poddir/$mandir/; # change the beginning of the path
|
||||
$manfile =~ s/\.pod$//; # change the ending
|
||||
my $mdir = $manfile;
|
||||
$mdir =~ s|/[^/]*$||; # get rid of the basename part
|
||||
if (system("mkdir -p $mdir")) { die "Error: could not create $mdir.\n"; }
|
||||
my ($section) = $podfile =~ /\.(\d+)\.pod$/;
|
||||
convertpod2man($podfile, $manfile, $section);
|
||||
}
|
||||
|
||||
my @dummyPods = createDummyPods($poddir, \@pods);
|
||||
|
||||
# Build the html page for each pod.
|
||||
#mkdir($htmldir) or die "Error: could not create $htmldir.\n";
|
||||
print "Converting PODs to HTML pages...\n";
|
||||
# have to clear the cache, because old entries can cause a problem
|
||||
unlink("$cachedir/pod2htmd.tmp", "$cachedir/pod2htmi.tmp");
|
||||
foreach my $podfile (@pods) {
|
||||
my $htmlfile = $podfile;
|
||||
$htmlfile =~ s/^$poddir/$htmldir/; # change the beginning of the path
|
||||
$htmlfile =~ s/\.pod$/\.html/; # change the ending
|
||||
my $hdir = $htmlfile;
|
||||
$hdir =~ s|/[^/]*$||; # get rid of the basename part
|
||||
if (system("mkdir -p $hdir")) { die "Error: could not create $hdir.\n"; }
|
||||
#print "$podfile, $htmlfile, $poddir, $htmldir\n";
|
||||
convertpod2html($podfile, $htmlfile, $poddir, $htmldir);
|
||||
}
|
||||
|
||||
# Remove the dummy pods
|
||||
unlink @dummyPods;
|
||||
rmdir "$poddir/man7";
|
||||
|
||||
exit;
|
||||
|
||||
|
||||
# To enable linking between the cmd man pages and the db man pages, need to:
|
||||
# grep thru the cmd pods searching for references (L<>) to any section 5 man page
|
||||
# if that pod does not exist, create an empty one that will satisfy pod2html
|
||||
# keep track of all dummy pods created, so they can be removed later
|
||||
sub createDummyPods {
|
||||
my ($poddir, $pods) = @_;
|
||||
my $cmd = "grep -r -E 'L<.+\\([57]\\)\\|.+\\.[57]>' " . $poddir;
|
||||
#print "Running cmd: ", $cmd, "\n";
|
||||
my @lines = `$cmd`;
|
||||
if ($?) { print "Error running: $cmd\n"; print join('', @lines); }
|
||||
#my @lines;
|
||||
#system($cmd);
|
||||
my @dummyPods;
|
||||
foreach my $l (@lines) {
|
||||
#print "$l\n";
|
||||
my @matches = $l =~ /L<([^\(]+)\(([57])\)\|\1\.[57]>/g; # get all the matches in the line
|
||||
# The above line should create the array with every other entry being the man page name
|
||||
# and every other entry is the section # (5 or 7)
|
||||
my $cmd;
|
||||
while ($cmd=shift @matches) {
|
||||
#foreach my $m (@matches) {
|
||||
my $section = shift @matches;
|
||||
my $filename = "$poddir/man$section/$cmd.$section.pod";
|
||||
#print "$filename\n";
|
||||
if (!(grep /^$filename$/, @$pods) && !(grep /^$filename$/, @dummyPods)) { push @dummyPods, $filename; }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# Create these empty files
|
||||
print "Creating empty linked-to files: ", join(', ', @dummyPods), "\n";
|
||||
mkdir "$poddir/man7";
|
||||
foreach my $d (@dummyPods) {
|
||||
if (!open(TMP, ">>$d")) { warn "Could not create dummy pod file $d ($!)\n"; }
|
||||
else { close TMP; }
|
||||
}
|
||||
|
||||
return @dummyPods;
|
||||
}
|
||||
|
||||
# Recursively get the list of pod man page files.
|
||||
sub getPodList {
|
||||
my $poddir = shift;
|
||||
my @files;
|
||||
|
||||
# 1st get toplevel dir listing
|
||||
opendir(DIR, $poddir) or die "Error: could not read $poddir.\n";
|
||||
my @topdir = grep !/^\./, readdir(DIR); # /
|
||||
close(DIR);
|
||||
|
||||
# Now go thru each subdir (these are man1, man3, etc.)
|
||||
foreach my $mandir (@topdir) {
|
||||
opendir(DIR, "$poddir/$mandir") or die "Error: could not read $poddir/$mandir.\n";
|
||||
my @dir = grep !/^\./, readdir(DIR); # /
|
||||
close(DIR);
|
||||
foreach my $file (@dir) {
|
||||
push @files, "$poddir/$mandir/$file";
|
||||
}
|
||||
}
|
||||
return sort @files;
|
||||
}
|
||||
|
||||
|
||||
# Create the xcat man page that gives a summary description of each xcat cmd.
|
||||
# Not used
|
||||
sub writesummarypage {
|
||||
my $file = shift; # relative path file name of the man page
|
||||
# the rest of @_ contains the pod files that describe each cmd
|
||||
|
||||
open(FILE, ">$file") or die "Error: could not open $file for writing.\n";
|
||||
|
||||
print FILE <<'EOS1';
|
||||
=head1 NAME
|
||||
|
||||
B<xcat> - extreme Cluster Administration Tool.
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Extreme Cluster Administration Toolkit (xCAT). xCAT is a scalable distributed computing management
|
||||
and provisioning tool that provides a unified interface for hardware control, discovery, and
|
||||
OS diskful/diskfree deployment.
|
||||
|
||||
|
||||
=head1 XCAT DATABASE
|
||||
|
||||
All of the cluster configuration information is in the xCAT database. See L<xcatdb(5)|xcatdb.5> for
|
||||
descriptions of every table in the database.
|
||||
|
||||
=head1 XCAT COMMANDS
|
||||
|
||||
What follows is a short description of each xCAT command. To get more information about a particular
|
||||
command, see its man page. Note that the commands are listed in alphabetical order B<within each section>,
|
||||
i.e. all the commands in section 1, then the commands in section 3, etc.
|
||||
|
||||
=over 12
|
||||
EOS1
|
||||
|
||||
# extract the summary for each cmd from its man page
|
||||
foreach my $manpage (@_) {
|
||||
my ($sectionnum) = $manpage =~ /\.(\d+)\.pod$/;
|
||||
# Suck in the whole file, then we will parse it.
|
||||
open(MANPAGE, "$manpage") or die "Error: could not open $manpage for reading.\n";
|
||||
my @contents = <MANPAGE>;
|
||||
my $wholemanpage = join('', @contents);
|
||||
close(MANPAGE);
|
||||
# This regex matches: optional space, =head1, space, title, space, cmd, space, description, newline
|
||||
my ($cmd, $description) = $wholemanpage =~ /^\s*=head1\s+\S+\s+(\S+)\s+(.+?)\n/si;
|
||||
if (!defined($cmd)) { print "Warning: $manpage is not in a recognized structure. It will be ignored.\n"; next; }
|
||||
if (!defined($description)) { print "Warning: $manpage does not have a description for $cmd. It will be ignored.\n"; next; }
|
||||
$cmd =~ s/^.<(.+)>$/$1/; # if the cmd name has pod formatting around it, strip it off
|
||||
$description =~ s/^-\s*//; # if the description has a leading hypen, strip it off
|
||||
print FILE "\n=item L<$cmd($sectionnum)|$cmd.$sectionnum>\n\n".$description."\n";
|
||||
}
|
||||
|
||||
# Artificially add the xcattest cmd, because the xCAT-test rpm will add this
|
||||
print FILE "\n=item L<xcattest(1)|xcattest.1>\n\nRun automated xCAT test cases.\n";
|
||||
|
||||
print FILE <<"EOS3";
|
||||
|
||||
=back
|
||||
EOS3
|
||||
|
||||
close FILE;
|
||||
}
|
||||
|
||||
|
||||
# Create the html page for one pod.
|
||||
sub convertpod2html {
|
||||
my ($podfile, $htmlfile, $poddir, $htmldir) = @_;
|
||||
|
||||
#TODO: use --css=<stylesheet> and --title=<pagetitle> to make the pages look better
|
||||
pod2html($podfile,
|
||||
"--outfile=$htmlfile",
|
||||
"--podpath=man1",
|
||||
"--podroot=$poddir",
|
||||
"--htmldir=$htmldir",
|
||||
"--recurse",
|
||||
"--cachedir=$cachedir",
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
||||
# Create the man page for one pod.
|
||||
sub convertpod2man {
|
||||
my ($podfile, $manfile, $section) = @_;
|
||||
|
||||
my $parser = Pod::Man->new(section => $section);
|
||||
$parser->parse_from_file($podfile, $manfile);
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
include AUTHORS
|
||||
include ChangeLog
|
||||
exclude .gitignore
|
||||
exclude .gitreview
|
||||
|
||||
global-exclude *.pyc
|
||||
@@ -1,44 +0,0 @@
|
||||
xCAT Driver for ironic x86/64 machine
|
||||
==================================
|
||||
|
||||
xCAT is a Extreme Cluster/Cloud Administration Toolkit. We can use xcat
|
||||
to do :
|
||||
1 hardward discoveery
|
||||
2 remote hardware control
|
||||
3 remote sonsole
|
||||
4 hardware inventory
|
||||
5 firmware flashing
|
||||
|
||||
Ironic is a project in Openstack, it will replace the nova-baremetal in juno release. Ironic's design is very flexable, we can add driver to extend function
|
||||
without change any code in Openstack. Ironic xCAT driver takes the advantage of xcat and openstack, we can use it to deploy the baremetal machine very easily.
|
||||
|
||||
Before using this driver, we must setup the openstack environment at least for two nodes( ironic conductor and neutron network node can't setup on the same node)
|
||||
Ironic conductor and the baremetal node( waiting for deploy) must in the same vlan
|
||||
|
||||
Add the follows in the ironic egg-info entry_points.txt file (ironic.drivers section)
|
||||
|
||||
pxe_xcat = ironic.drivers.xcat:XCATBaremetalDriver
|
||||
|
||||
When the openstack with ironic is ready, just execute command in the ironic_xcat directory as follows:
|
||||
|
||||
$ python setup.py install
|
||||
|
||||
Restart the ironic-conductor process
|
||||
|
||||
Initialize the xcat environment according to http://sourceforge.net/p/xcat/wiki/XCAT_iDataPlex_Cluster_Quick_Start/
|
||||
Using xCAT baremetal driver need config site table and run copycds to generate image. The node definition is not requirement.
|
||||
|
||||
Ironic use neutron as the network service.
|
||||
Check the openvswitch config on the network node ,make sure brbm bridge connect to the baremetal node.
|
||||
|
||||
==================================================================================
|
||||
Some Example to use the xCAT baremetal driver.
|
||||
|
||||
$touch /tmp/rhelhpc6.5-x86_64-install-compute.qcow2;glance image-create --name rhelhpc6.5-x86_64-install-compute --public --disk-format qcow2 --container-format bare --property xcat_image_name='rhels6.4-x86_64-install-compute' < /tmp/rhelhpc6.5-x86_64-install-compute.qcow2
|
||||
--name rhelhpc6.5-x86_64-install-compute is the image name in xcat. You can use lsdef -t osimage on the ironic-conductor node which xcat is installed.
|
||||
|
||||
$ ironic node-create --driver pxe_xcat -i ipmi_address=xxx.xxx.xxx.xxx -i ipmi_username=userid -i ipmi_password=password -i xcat_node=x3550m4n02 -i xcatmaster=10.1.0.241 -i netboot=xnba -i ipmi_terminal_port=0 -p memory_mb=2048 -p cpus=8
|
||||
|
||||
$ ironic port-create --address ff:ff:ff:ff:ff:ff --node_uuid <ironic node uuid>
|
||||
|
||||
$ nova boot --flavor baremetal --image <image-id> testing --nic net-id=<internal network id>
|
||||
@@ -1,25 +0,0 @@
|
||||
"""xCAT baremtal exceptions.
|
||||
"""
|
||||
|
||||
from oslo.config import cfg
|
||||
import six
|
||||
|
||||
from ironic.openstack.common.gettextutils import _
|
||||
from ironic.openstack.common import log as logging
|
||||
from ironic.common.exception import IronicException
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
class xCATCmdFailure(IronicException):
|
||||
message = _("xcat call failed: %(cmd)s %(node)s %(args)s.")
|
||||
|
||||
class xCATDeploymentFailure(IronicException):
|
||||
message = _("xCAT node deployment failed for node %(node)s:%(error)s")
|
||||
|
||||
class GetNetworkFixedIPFailure(IronicException):
|
||||
message = _("get fixed ip failed for mac %(mac_address)s")
|
||||
|
||||
class GetNetworkIdFailure(IronicException):
|
||||
message = _("get node network in failed for mac %(mac_address)s")
|
||||
|
||||
class FailedToGetInfoOnPort(IronicException):
|
||||
message = _("Show info on port: %(port_id)s failed.")
|
||||
@@ -1,41 +0,0 @@
|
||||
"""
|
||||
Get the network from neutron
|
||||
This is a xcat patch for the ironic/common/neutron.py
|
||||
"""
|
||||
|
||||
from neutronclient.common import exceptions as neutron_client_exc
|
||||
from ironic.common import exception
|
||||
from ironic.openstack.common import log as logging
|
||||
from ironic.common import neutron
|
||||
from ironic.drivers.modules import xcat_exception
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
def get_vif_port_info(task, port_id):
|
||||
""" Get detail port info from neutron with a given port id """
|
||||
api = neutron.NeutronAPI(task.context)
|
||||
try:
|
||||
port_info = api.client.show_port(port_id)
|
||||
except neutron_client_exc.NeutronClientException:
|
||||
LOG.exception(_("Failed to get port info %s."), port_id)
|
||||
raise exception.FailedToGetInfoOnPort(port_id=port_id)
|
||||
return port_info
|
||||
|
||||
|
||||
def get_ports_info_from_neutron(task):
|
||||
""" Get neutron port info from neutron about this task """
|
||||
vifs = neutron.get_node_vif_ids(task)
|
||||
if not vifs:
|
||||
LOG.warning(_("No VIFs found for node %(node)s when attempting to "
|
||||
"update Neutron DHCP BOOT options."),
|
||||
{'node': task.node.uuid})
|
||||
return
|
||||
failures = []
|
||||
vif_ports_info = {}
|
||||
for port_id, port_vif in vifs.iteritems():
|
||||
try:
|
||||
vif_ports_info[port_id] = get_vif_port_info(task,port_vif)
|
||||
except xcat_exception.FailedToGetInfoOnPort(port_id=port_vif):
|
||||
failures.append(port_vif)
|
||||
return vif_ports_info
|
||||
|
||||
@@ -1,453 +0,0 @@
|
||||
"""
|
||||
pxe procedure for the xcat baremetal driver
|
||||
use xcat to config dhcp and tftp
|
||||
"""
|
||||
|
||||
import os
|
||||
import time
|
||||
import paramiko
|
||||
import datetime
|
||||
from oslo.config import cfg
|
||||
from ironic.common import exception
|
||||
from ironic.common import image_service as service
|
||||
from ironic.common import keystone
|
||||
from ironic.common import states
|
||||
from ironic.common import utils
|
||||
from ironic.conductor import task_manager
|
||||
from ironic.conductor import utils as manager_utils
|
||||
from ironic.drivers import base
|
||||
from ironic.drivers import utils as driver_utils
|
||||
from ironic.openstack.common import log as logging
|
||||
from ironic.openstack.common import strutils
|
||||
from ironic.drivers.modules import xcat_neutron
|
||||
from ironic.drivers.modules import xcat_util
|
||||
from ironic.openstack.common import loopingcall
|
||||
from nova.openstack.common import timeutils
|
||||
from ironic.openstack.common import lockutils
|
||||
from ironic.drivers.modules import xcat_exception
|
||||
|
||||
|
||||
pxe_opts = [
|
||||
cfg.StrOpt('pxe_append_params',
|
||||
default='nofb nomodeset vga=normal',
|
||||
help='Additional append parameters for baremetal PXE boot.'),
|
||||
cfg.StrOpt('default_ephemeral_format',
|
||||
default='ext4',
|
||||
help='Default file system format for ephemeral partition, '
|
||||
'if one is created.'),
|
||||
]
|
||||
xcat_opts = [
|
||||
cfg.StrOpt('network_node_ip',
|
||||
default='127.0.0.1',
|
||||
help='IP address of neutron network node'),
|
||||
cfg.StrOpt('ssh_user',
|
||||
default='root',
|
||||
help='Username of neutron network node.'),
|
||||
cfg.StrOpt('ssh_password',
|
||||
default='cluster',
|
||||
help='Password of neutron network node'),
|
||||
cfg.IntOpt('ssh_port',
|
||||
default=22,
|
||||
help='ssh connection port for the neutron '),
|
||||
cfg.StrOpt('host_filepath',
|
||||
default='/etc/hosts',
|
||||
help='host file of server'),
|
||||
cfg.IntOpt('deploy_timeout',
|
||||
default=3600,
|
||||
help='max depolyment time(seconds) for the xcat driver'),
|
||||
cfg.IntOpt('deploy_checking_interval',
|
||||
default=30,
|
||||
help='interval time(seconds) to check the xcat deploy state'),
|
||||
]
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
CONF = cfg.CONF
|
||||
CONF.register_opts(pxe_opts, group='pxe')
|
||||
CONF.register_opts(xcat_opts, group='xcat')
|
||||
CONF.import_opt('use_ipv6', 'ironic.netconf')
|
||||
|
||||
EM_SEMAPHORE = 'xcat_pxe'
|
||||
|
||||
def _check_for_missing_params(info_dict, param_prefix=''):
|
||||
missing_info = []
|
||||
for label, value in info_dict.items():
|
||||
if not value:
|
||||
missing_info.append(param_prefix + label)
|
||||
|
||||
if missing_info:
|
||||
raise exception.InvalidParameterValue(_(
|
||||
"Can not validate PXE bootloader. The following parameters "
|
||||
"were not passed to ironic: %s") % missing_info)
|
||||
|
||||
def _parse_driver_info(node):
|
||||
"""Gets the driver specific Node deployment info.
|
||||
|
||||
This method validates whether the 'driver_info' property of the
|
||||
supplied node contains the required information for this driver to
|
||||
deploy images to the node.
|
||||
|
||||
:param node: a single Node.
|
||||
:returns: A dict with the driver_info values.
|
||||
"""
|
||||
info = node.driver_info
|
||||
d_info = {}
|
||||
d_info['xcat_node'] = info.get('xcat_node')
|
||||
return d_info
|
||||
|
||||
def _parse_instance_info(node):
|
||||
"""Gets the instance specific Node deployment info.
|
||||
|
||||
This method validates whether the 'instance_info' property of the
|
||||
supplied node contains the required information for this driver to
|
||||
deploy images to the node.
|
||||
|
||||
:param node: a single Node.
|
||||
:returns: A dict with the instance_info values.
|
||||
"""
|
||||
|
||||
info = node.instance_info
|
||||
i_info = {}
|
||||
i_info['image_source'] = info.get('image_source')
|
||||
i_info['root_gb'] = info.get('root_gb')
|
||||
i_info['image_file'] = i_info['image_source']
|
||||
|
||||
_check_for_missing_params(i_info)
|
||||
|
||||
# Internal use only
|
||||
i_info['deploy_key'] = info.get('deploy_key')
|
||||
|
||||
i_info['swap_mb'] = info.get('swap_mb', 0)
|
||||
i_info['ephemeral_gb'] = info.get('ephemeral_gb', 0)
|
||||
i_info['ephemeral_format'] = info.get('ephemeral_format')
|
||||
|
||||
err_msg_invalid = _("Can not validate PXE bootloader. Invalid parameter "
|
||||
"%(param)s. Reason: %(reason)s")
|
||||
for param in ('root_gb', 'swap_mb', 'ephemeral_gb'):
|
||||
try:
|
||||
int(i_info[param])
|
||||
except ValueError:
|
||||
reason = _("'%s' is not an integer value.") % i_info[param]
|
||||
raise exception.InvalidParameterValue(err_msg_invalid %
|
||||
{'param': param, 'reason': reason})
|
||||
|
||||
if i_info['ephemeral_gb'] and not i_info['ephemeral_format']:
|
||||
i_info['ephemeral_format'] = CONF.pxe.default_ephemeral_format
|
||||
|
||||
preserve_ephemeral = info.get('preserve_ephemeral', False)
|
||||
try:
|
||||
i_info['preserve_ephemeral'] = strutils.bool_from_string(
|
||||
preserve_ephemeral, strict=True)
|
||||
except ValueError as e:
|
||||
raise exception.InvalidParameterValue(err_msg_invalid %
|
||||
{'param': 'preserve_ephemeral', 'reason': e})
|
||||
return i_info
|
||||
|
||||
|
||||
def _parse_deploy_info(node):
|
||||
"""Gets the instance and driver specific Node deployment info.
|
||||
|
||||
This method validates whether the 'instance_info' and 'driver_info'
|
||||
property of the supplied node contains the required information for
|
||||
this driver to deploy images to the node.
|
||||
|
||||
:param node: a single Node.
|
||||
:returns: A dict with the instance_info and driver_info values.
|
||||
"""
|
||||
info = {}
|
||||
info.update(_parse_instance_info(node))
|
||||
info.update(_parse_driver_info(node))
|
||||
return info
|
||||
|
||||
def _validate_glance_image(ctx, deploy_info):
|
||||
"""Validate the image in Glance.
|
||||
|
||||
Check if the image exist in Glance and if it contains the
|
||||
'kernel_id' and 'ramdisk_id' properties.
|
||||
|
||||
:raises: InvalidParameterValue.
|
||||
"""
|
||||
image_id = deploy_info['image_source']
|
||||
if not image_id:
|
||||
raise exception.ImageNotFound
|
||||
|
||||
class PXEDeploy(base.DeployInterface):
|
||||
"""PXE Deploy Interface: just a stub until the real driver is ported."""
|
||||
|
||||
def validate(self, task):
|
||||
"""Validate the deployment information for the task's node.
|
||||
|
||||
:param task: a TaskManager instance containing the node to act on.
|
||||
:raises: InvalidParameterValue.
|
||||
"""
|
||||
node = task.node
|
||||
if not driver_utils.get_node_mac_addresses(task):
|
||||
raise exception.InvalidParameterValue(_("Node %s does not have "
|
||||
"any port associated with it.") % node.uuid)
|
||||
|
||||
d_info = _parse_deploy_info(node)
|
||||
# Try to get the URL of the Ironic API
|
||||
try:
|
||||
# TODO(lucasagomes): Validate the format of the URL
|
||||
CONF.conductor.api_url or keystone.get_service_url()
|
||||
except (exception.CatalogFailure,
|
||||
exception.CatalogNotFound,
|
||||
exception.CatalogUnauthorized):
|
||||
raise exception.InvalidParameterValue(_(
|
||||
"Couldn't get the URL of the Ironic API service from the "
|
||||
"configuration file or keystone catalog."))
|
||||
|
||||
_validate_glance_image(task.context, d_info)
|
||||
|
||||
@task_manager.require_exclusive_lock
|
||||
def deploy(self, task):
|
||||
"""Start deployment of the task's node'.
|
||||
|
||||
Config host file and xcat dhcp, generate image info for xcat
|
||||
and issues a reboot request to the power driver.
|
||||
This causes the node to boot into the deployment ramdisk and triggers
|
||||
the next phase of PXE-based deployment via
|
||||
VendorPassthru._continue_deploy().
|
||||
|
||||
:param task: a TaskManager instance containing the node to act on.
|
||||
:returns: deploy state DEPLOYDONE.
|
||||
"""
|
||||
|
||||
d_info = _parse_deploy_info(task.node)
|
||||
if not task.node.instance_info.get('fixed_ip_address') or not task.node.instance_info.get('image_name'):
|
||||
raise exception.InvalidParameterValue
|
||||
self._config_host_file(d_info,task.node.instance_info.get('fixed_ip_address'))
|
||||
self._make_dhcp()
|
||||
self._nodeset_osimage(d_info,task.node.instance_info.get('image_name'))
|
||||
manager_utils.node_set_boot_device(task, 'pxe', persistent=True)
|
||||
manager_utils.node_power_action(task, states.REBOOT)
|
||||
try:
|
||||
self._wait_for_node_deploy(task)
|
||||
except xcat_exception.xCATDeploymentFailure:
|
||||
LOG.info(_("xcat deployment failed"))
|
||||
return states.ERROR
|
||||
|
||||
return states.DEPLOYDONE
|
||||
|
||||
@task_manager.require_exclusive_lock
|
||||
def tear_down(self, task):
|
||||
"""Tear down a previous deployment on the task's node.
|
||||
|
||||
Power off the node. All actual clean-up is done in the clean_up()
|
||||
method which should be called separately.
|
||||
|
||||
:param task: a TaskManager instance containing the node to act on.
|
||||
:returns: deploy state DELETED.
|
||||
"""
|
||||
manager_utils.node_power_action(task, states.POWER_OFF)
|
||||
return states.DELETED
|
||||
|
||||
def prepare(self, task):
|
||||
"""Prepare the deployment environment for this task's node.
|
||||
Get the image info from glance, config the mac for the xcat
|
||||
use ssh and iptables to disable dhcp on network node
|
||||
:param task: a TaskManager instance containing the node to act on.
|
||||
"""
|
||||
# TODO(deva): optimize this if rerun on existing files
|
||||
d_info = _parse_deploy_info(task.node)
|
||||
i_info = task.node.instance_info
|
||||
image_id = d_info['image_source']
|
||||
try:
|
||||
glance_service = service.Service(version=1, context=task.context)
|
||||
image_name = glance_service.show(image_id)['name']
|
||||
i_info['image_name'] = image_name
|
||||
except (exception.GlanceConnectionFailed,
|
||||
exception.ImageNotAuthorized,
|
||||
exception.Invalid):
|
||||
LOG.warning(_("Failed to connect to Glance to get the properties "
|
||||
"of the image %s") % image_id)
|
||||
|
||||
node_mac_addresses = driver_utils.get_node_mac_addresses(task)
|
||||
vif_ports_info = xcat_neutron.get_ports_info_from_neutron(task)
|
||||
try:
|
||||
network_info = self._get_deploy_network_info(vif_ports_info, node_mac_addresses)
|
||||
except (xcat_exception.GetNetworkFixedIPFailure,xcat_exception.GetNetworkIdFailure):
|
||||
LOG.error(_("Failed to get network info"))
|
||||
return
|
||||
if not network_info:
|
||||
LOG.error(_("Failed to get network info"))
|
||||
return
|
||||
|
||||
fixed_ip_address = network_info['fixed_ip_address']
|
||||
deploy_mac_address = network_info['mac_address']
|
||||
network_id = network_info['network_id']
|
||||
|
||||
i_info['fixed_ip_address'] = fixed_ip_address
|
||||
i_info['network_id'] = network_id
|
||||
i_info['deploy_mac_address'] = deploy_mac_address
|
||||
|
||||
# use iptables to drop the dhcp mac of baremetal machine
|
||||
self._ssh_append_dhcp_rule(CONF.xcat.network_node_ip,CONF.xcat.ssh_port,CONF.xcat.ssh_user,
|
||||
CONF.xcat.ssh_password,network_id,deploy_mac_address)
|
||||
self._chdef_node_mac_address(d_info,deploy_mac_address)
|
||||
|
||||
def clean_up(self, task):
|
||||
"""Clean up the deployment environment for the task's node.
|
||||
|
||||
Unlinks TFTP and instance images and triggers image cache cleanup.
|
||||
Removes the TFTP configuration files for this node. As a precaution,
|
||||
this method also ensures the keystone auth token file was removed.
|
||||
|
||||
:param task: a TaskManager instance containing the node to act on.
|
||||
"""
|
||||
pass
|
||||
|
||||
def take_over(self, task):
|
||||
pass
|
||||
|
||||
def _get_deploy_network_info(self, vif_ports_info, valid_node_mac_addrsses):
|
||||
"""Get network info from mac address of ironic node.
|
||||
:param vif_ports_info: info collection from neutron ports
|
||||
:param valid_node_mac_addrsses: mac address from ironic node
|
||||
:raises: GetNetworkFixedIpFailure if search the fixed ip from mac address failure
|
||||
:raises: GetNetworkIdFailure if search the network id from mac address failure
|
||||
"""
|
||||
network_info = {}
|
||||
for port_info in vif_ports_info.values():
|
||||
if(port_info['port']['mac_address'] in valid_node_mac_addrsses ):
|
||||
network_info['fixed_ip_address'] = port_info['port']['fixed_ips'][0]['ip_address']
|
||||
if not network_info['fixed_ip_address']:
|
||||
raise xcat_exception.GetNetworkFixedIPFailure(mac_address=port_info['port']['mac_address'])
|
||||
network_info['mac_address'] = port_info['port']['mac_address']
|
||||
network_info['network_id'] = port_info['port']['network_id']
|
||||
if not network_info['network_id']:
|
||||
raise xcat_exception.GetNetworkIdFailure(mac_address=port_info['port']['mac_address'])
|
||||
network_info['port_id'] = port_info['port']['id']
|
||||
return network_info
|
||||
return network_info
|
||||
|
||||
def _chdef_node_mac_address(self, driver_info, deploy_mac):
|
||||
""" run chdef command to set mac address"""
|
||||
cmd = 'chdef'
|
||||
args = 'mac='+ deploy_mac
|
||||
try:
|
||||
out_err = xcat_util.exec_xcatcmd(driver_info, cmd, args)
|
||||
LOG.info(_("xcat chdef cmd exetute output: %(out_err)s") % {'out_err':out_err})
|
||||
except xcat_exception.xCATCmdFailure as e:
|
||||
LOG.warning(_("xcat chdef failed for node %(xcat_node)s with "
|
||||
"error: %(error)s.")
|
||||
% {'xcat_node': driver_info['xcat_node'], 'error': e})
|
||||
raise exception.IPMIFailure(cmd=cmd)
|
||||
|
||||
@lockutils.synchronized(EM_SEMAPHORE, 'xcat-hosts-')
|
||||
def _config_host_file(self, driver_info, deploy_ip):
|
||||
""" append node and ip infomation to host file"""
|
||||
with open(CONF.xcat.host_filepath,"r+") as f:
|
||||
lines = []
|
||||
for line in f:
|
||||
temp = line.split('#')
|
||||
if temp[0].strip():
|
||||
host_name = xcat_util._tsplit(temp[0].strip(),(' ','\t'))[1]
|
||||
if driver_info['xcat_node'] not in host_name:
|
||||
lines.append(line)
|
||||
|
||||
# append a new line to host file
|
||||
line = "%s\t%s\n" %(deploy_ip,driver_info['xcat_node'])
|
||||
lines.append(line)
|
||||
f.seek(0)
|
||||
f.truncate()
|
||||
for line in lines:
|
||||
f.write(line)
|
||||
|
||||
def _nodeset_osimage(self, driver_info, image_name):
|
||||
"""run nodeset command to config the image for the xcat node
|
||||
:param driver_info: xcat node deploy info
|
||||
:param image_name: image for the xcat deployment
|
||||
"""
|
||||
cmd = 'nodeset'
|
||||
args = 'osimage='+ image_name
|
||||
try:
|
||||
xcat_util.exec_xcatcmd(driver_info, cmd, args)
|
||||
except xcat_exception.xCATCmdFailure as e:
|
||||
LOG.warning(_("xcat nodeset failed for node %(xcat_node)s with "
|
||||
"error: %(error)s.")
|
||||
% {'xcat_node': driver_info['xcat_node'], 'error': e})
|
||||
|
||||
def _make_dhcp(self):
|
||||
"""run makedhcp command to setup dhcp environment for the xcat node"""
|
||||
cmd = ['makedhcp',
|
||||
'-n'
|
||||
]
|
||||
try:
|
||||
out, err = utils.execute(*cmd)
|
||||
LOG.info(_(" excute cmd: %(cmd)s \n output: %(out)s \n. Error: %(err)s \n"),
|
||||
{'cmd':cmd,'out': out, 'err': err})
|
||||
except Exception as e:
|
||||
LOG.error(_("Unable to execute %(cmd)s. Exception: %(exception)s"),
|
||||
{'cmd': cmd, 'exception': e})
|
||||
# makedhcp -a
|
||||
cmd = ['makedhcp',
|
||||
'-a'
|
||||
]
|
||||
try:
|
||||
out, err = utils.execute(*cmd)
|
||||
LOG.info(_(" excute cmd: %(cmd)s \n output: %(out)s \n. Error: %(err)s \n"),
|
||||
{'cmd':cmd,'out': out, 'err': err})
|
||||
except Exception as e:
|
||||
LOG.error(_("Unable to execute %(cmd)s. Exception: %(exception)s"),
|
||||
{'cmd': cmd, 'exception': e})
|
||||
|
||||
def _ssh_append_dhcp_rule(self,ip,port,username,password,network_id,mac_address):
|
||||
""" drop the dhcp package in network node to avoid of confilct of dhcp """
|
||||
netns = 'qdhcp-%s' %network_id
|
||||
append_cmd = 'sudo ip netns exec %s iptables -A INPUT -m mac --mac-source %s -j DROP' % \
|
||||
(netns,mac_address)
|
||||
cmd = [append_cmd]
|
||||
xcat_util.xcat_ssh(ip,port,username,password,cmd)
|
||||
|
||||
def _ssh_delete_dhcp_rule(self,ip,port,username,password,network_id,mac_address):
|
||||
""" delete the iptable rule on network node to recover the environment"""
|
||||
netns = 'qdhcp-%s' %network_id
|
||||
cancel_cmd = 'sudo ip netns exec %s iptables -D INPUT -m mac --mac-source %s -j DROP' % \
|
||||
(netns,mac_address)
|
||||
cmd = [cancel_cmd]
|
||||
xcat_util.xcat_ssh(ip,port,username,password,cmd)
|
||||
|
||||
def _wait_for_node_deploy(self, task):
|
||||
"""Wait for xCAT node deployment to complete."""
|
||||
locals = {'errstr':''}
|
||||
driver_info = _parse_deploy_info(task.node)
|
||||
node_mac_addrsses = driver_utils.get_node_mac_addresses(task)
|
||||
i_info = task.node.instance_info
|
||||
|
||||
def _wait_for_deploy():
|
||||
out,err = xcat_util.exec_xcatcmd(driver_info,'nodels','nodelist.status')
|
||||
if err:
|
||||
locals['errstr'] = _("Error returned when quering node status"
|
||||
" for node %s:%s") % (driver_info['xcat_node'], err)
|
||||
LOG.warning(locals['errstr'])
|
||||
raise loopingcall.LoopingCallDone()
|
||||
|
||||
if out:
|
||||
node,status = out.split(": ")
|
||||
status = status.strip()
|
||||
if status == "booted":
|
||||
LOG.info(_("Deployment for node %s completed.")
|
||||
% driver_info['xcat_node'])
|
||||
raise loopingcall.LoopingCallDone()
|
||||
|
||||
if (CONF.xcat.deploy_timeout and
|
||||
timeutils.utcnow() > expiration):
|
||||
locals['errstr'] = _("Timeout while waiting for"
|
||||
" deployment of node %s.") % driver_info['xcat_node']
|
||||
LOG.warning(locals['errstr'])
|
||||
raise loopingcall.LoopingCallDone()
|
||||
|
||||
expiration = timeutils.utcnow() + datetime.timedelta(
|
||||
seconds=CONF.xcat.deploy_timeout)
|
||||
timer = loopingcall.FixedIntervalLoopingCall(_wait_for_deploy)
|
||||
# default check every 10 seconds
|
||||
timer.start(interval=CONF.xcat.deploy_checking_interval).wait()
|
||||
|
||||
if locals['errstr']:
|
||||
raise xcat_exception.xCATDeploymentFailure(locals['errstr'])
|
||||
# deploy end, delete the dhcp rule for xcat
|
||||
self._ssh_delete_dhcp_rule(CONF.xcat.network_node_ip,CONF.xcat.ssh_port,CONF.xcat.ssh_user,
|
||||
CONF.xcat.ssh_password,i_info['network_id'],node_mac_addrsses[0])
|
||||
|
||||
|
||||
@@ -1,479 +0,0 @@
|
||||
|
||||
"""
|
||||
IPMI power manager driver.
|
||||
"""
|
||||
|
||||
import contextlib
|
||||
import os
|
||||
import stat
|
||||
import tempfile
|
||||
import time
|
||||
|
||||
from oslo.config import cfg
|
||||
|
||||
from ironic.common import exception
|
||||
from ironic.common import states
|
||||
from ironic.common import utils
|
||||
from ironic.conductor import task_manager
|
||||
from ironic.drivers import base
|
||||
from ironic.drivers.modules import console_utils
|
||||
from ironic.openstack.common import excutils
|
||||
from ironic.openstack.common import log as logging
|
||||
from ironic.openstack.common import loopingcall
|
||||
from ironic.openstack.common import processutils
|
||||
from ironic.drivers.modules import xcat_exception
|
||||
from ironic.drivers.modules import xcat_util
|
||||
|
||||
CONF = cfg.CONF
|
||||
CONF.import_opt('retry_timeout',
|
||||
'ironic.drivers.modules.ipminative',
|
||||
group='ipmi')
|
||||
CONF.import_opt('min_command_interval',
|
||||
'ironic.drivers.modules.ipminative',
|
||||
group='ipmi')
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
VALID_BOOT_DEVICES = ['net', 'hd', 'cd', 'floppy', 'def', 'stat']
|
||||
VALID_PRIV_LEVELS = ['ADMINISTRATOR', 'CALLBACK', 'OPERATOR', 'USER']
|
||||
TIMING_SUPPORT = None
|
||||
|
||||
|
||||
def _is_timing_supported(is_supported=None):
|
||||
# shim to allow module variable to be mocked in unit tests
|
||||
global TIMING_SUPPORT
|
||||
|
||||
if (TIMING_SUPPORT is None) and (is_supported is not None):
|
||||
TIMING_SUPPORT = is_supported
|
||||
return TIMING_SUPPORT
|
||||
|
||||
|
||||
def check_timing_support():
|
||||
"""Check the installed version of ipmitool for -N -R option support.
|
||||
|
||||
Support was added in 1.8.12 for the -N -R options, which enable
|
||||
more precise control over timing of ipmi packets. Prior to this,
|
||||
the default behavior was to retry each command up to 18 times at
|
||||
1 to 5 second intervals.
|
||||
http://ipmitool.cvs.sourceforge.net/viewvc/ipmitool/ipmitool/ChangeLog?revision=1.37 # noqa
|
||||
|
||||
This method updates the module-level TIMING_SUPPORT variable so that
|
||||
it is accessible by any driver interface class in this module. It is
|
||||
intended to be called from the __init__ method of such classes only.
|
||||
|
||||
:returns: boolean indicating whether support for -N -R is present
|
||||
:raises: OSError
|
||||
"""
|
||||
if _is_timing_supported() is None:
|
||||
# Directly check ipmitool for support of -N and -R options. Because
|
||||
# of the way ipmitool processes' command line options, if the local
|
||||
# ipmitool does not support setting the timing options, the command
|
||||
# below will fail.
|
||||
try:
|
||||
out, err = utils.execute(*['ipmitool', '-N', '0', '-R', '0', '-h'])
|
||||
except processutils.ProcessExecutionError:
|
||||
# the local ipmitool does not support the -N and -R options.
|
||||
_is_timing_supported(False)
|
||||
else:
|
||||
# looks like ipmitool supports timing options.
|
||||
_is_timing_supported(True)
|
||||
|
||||
|
||||
def _console_pwfile_path(uuid):
|
||||
"""Return the file path for storing the ipmi password for a console."""
|
||||
file_name = "%(uuid)s.pw" % {'uuid': uuid}
|
||||
return os.path.join(tempfile.gettempdir(), file_name)
|
||||
|
||||
def _parse_driver_info(node):
|
||||
"""Gets the parameters required for ipmitool to access the node.
|
||||
|
||||
:param node: the Node of interest.
|
||||
:returns: dictionary of parameters.
|
||||
:raises: InvalidParameterValue if any required parameters are missing.
|
||||
|
||||
"""
|
||||
info = node.driver_info or {}
|
||||
address = info.get('ipmi_address')
|
||||
username = info.get('ipmi_username')
|
||||
password = info.get('ipmi_password')
|
||||
port = info.get('ipmi_terminal_port')
|
||||
priv_level = info.get('ipmi_priv_level', 'ADMINISTRATOR')
|
||||
xcat_node = info.get('xcat_node')
|
||||
xcatmaster = info.get('xcatmaster')
|
||||
netboot = info.get('netboot')
|
||||
|
||||
if port:
|
||||
try:
|
||||
port = int(port)
|
||||
except ValueError:
|
||||
raise exception.InvalidParameterValue(_(
|
||||
"IPMI terminal port is not an integer."))
|
||||
|
||||
if not address:
|
||||
raise exception.InvalidParameterValue(_(
|
||||
"IPMI address not supplied to xcat driver."))
|
||||
|
||||
if priv_level not in VALID_PRIV_LEVELS:
|
||||
valid_priv_lvls = ', '.join(VALID_PRIV_LEVELS)
|
||||
raise exception.InvalidParameterValue(_(
|
||||
"Invalid privilege level value:%(priv_level)s, the valid value"
|
||||
" can be one of %(valid_levels)s") %
|
||||
{'priv_level': priv_level, 'valid_levels': valid_priv_lvls})
|
||||
|
||||
if not xcat_node:
|
||||
raise exception.InvalidParameterValue(_(
|
||||
"xcat node name not supplied to xcat driver"))
|
||||
|
||||
if not xcatmaster:
|
||||
raise exception.InvalidParameterValue(_(
|
||||
"xcatmaster not supplied to xcat driver"))
|
||||
|
||||
if not netboot:
|
||||
raise exception.InvalidParameterValue(_(
|
||||
"netboot not supplied to xcat driver"))
|
||||
|
||||
return {
|
||||
'address': address,
|
||||
'username': username,
|
||||
'password': password,
|
||||
'port': port,
|
||||
'uuid': node.uuid,
|
||||
'priv_level': priv_level,
|
||||
'xcat_node': xcat_node,
|
||||
'xcatmaster': xcatmaster,
|
||||
'netboot': netboot
|
||||
}
|
||||
def chdef_node(driver_info):
|
||||
"""Run the chdef command in xcat, config the node
|
||||
:param driver_info: driver_info for the xcat node
|
||||
"""
|
||||
cmd = 'chdef'
|
||||
args = 'mgt=ipmi' + \
|
||||
' bmc=' + driver_info['address'] + \
|
||||
' bmcusername=' + driver_info['username'] + \
|
||||
' bmcpassword=' + driver_info['password'] + \
|
||||
' xcatmaster=' + driver_info['xcatmaster']+ \
|
||||
' netboot=' + driver_info['netboot']+ \
|
||||
' primarynic=mac'+ \
|
||||
' installnic=mac'+ \
|
||||
' monserver=' + driver_info['xcatmaster'] + \
|
||||
' nfsserver=' + driver_info['xcatmaster'] + \
|
||||
' serialflow=hard'+ \
|
||||
' serialspeed=115200' + \
|
||||
' serialport=' + str(driver_info['port']);
|
||||
|
||||
try:
|
||||
xcat_util.exec_xcatcmd(driver_info, cmd, args)
|
||||
except xcat_exception.xCATCmdFailure as e:
|
||||
LOG.warning(_("xcat chdef failed for node %(node_id)s with "
|
||||
"error: %(error)s.")
|
||||
% {'node_id': driver_info['uuid'], 'error': e})
|
||||
|
||||
def _sleep_time(iter):
|
||||
"""Return the time-to-sleep for the n'th iteration of a retry loop.
|
||||
This implementation increases exponentially.
|
||||
|
||||
:param iter: iteration number
|
||||
:returns: number of seconds to sleep
|
||||
|
||||
"""
|
||||
if iter <= 1:
|
||||
return 1
|
||||
return iter ** 2
|
||||
|
||||
|
||||
def _set_and_wait(target_state, driver_info):
|
||||
"""Helper function for DynamicLoopingCall.
|
||||
|
||||
This method changes the power state and polls the BMCuntil the desired
|
||||
power state is reached, or CONF.ipmi.retry_timeout would be exceeded by the
|
||||
next iteration.
|
||||
|
||||
This method assumes the caller knows the current power state and does not
|
||||
check it prior to changing the power state. Most BMCs should be fine, but
|
||||
if a driver is concerned, the state should be checked prior to calling this
|
||||
method.
|
||||
|
||||
:param target_state: desired power state
|
||||
:param driver_info: the ipmitool parameters for accessing a node.
|
||||
:returns: one of ironic.common.states
|
||||
:raises: IPMIFailure on an error from ipmitool (from _power_status call).
|
||||
|
||||
"""
|
||||
if target_state == states.POWER_ON:
|
||||
state_name = "on"
|
||||
elif target_state == states.POWER_OFF:
|
||||
state_name = "off"
|
||||
|
||||
def _wait(mutable):
|
||||
try:
|
||||
# Only issue power change command once
|
||||
if mutable['iter'] < 0:
|
||||
xcat_util.exec_xcatcmd(driver_info,'rpower',state_name)
|
||||
else:
|
||||
mutable['power'] = _power_status(driver_info)
|
||||
except Exception:
|
||||
# Log failures but keep trying
|
||||
LOG.warning(_("xcat rpower %(state)s failed for node %(node)s."),
|
||||
{'state': state_name, 'node': driver_info['uuid']})
|
||||
finally:
|
||||
mutable['iter'] += 1
|
||||
|
||||
if mutable['power'] == target_state:
|
||||
raise loopingcall.LoopingCallDone()
|
||||
|
||||
sleep_time = _sleep_time(mutable['iter'])
|
||||
if (sleep_time + mutable['total_time']) > CONF.ipmi.retry_timeout:
|
||||
# Stop if the next loop would exceed maximum retry_timeout
|
||||
LOG.error(_('xcat rpower %(state)s timed out after '
|
||||
'%(tries)s retries on node %(node_id)s.'),
|
||||
{'state': state_name, 'tries': mutable['iter'],
|
||||
'node_id': driver_info['uuid']})
|
||||
mutable['power'] = states.ERROR
|
||||
raise loopingcall.LoopingCallDone()
|
||||
else:
|
||||
mutable['total_time'] += sleep_time
|
||||
return sleep_time
|
||||
|
||||
# Use mutable objects so the looped method can change them.
|
||||
# Start 'iter' from -1 so that the first two checks are one second apart.
|
||||
status = {'power': None, 'iter': -1, 'total_time': 0}
|
||||
|
||||
timer = loopingcall.DynamicLoopingCall(_wait, status)
|
||||
timer.start().wait()
|
||||
return status['power']
|
||||
|
||||
def _power_on(driver_info):
|
||||
"""Turn the power ON for this node.
|
||||
|
||||
:param driver_info: the xcat parameters for accessing a node.
|
||||
:returns: one of ironic.common.states POWER_ON or ERROR.
|
||||
:raises: IPMIFailure on an error from ipmitool (from _power_status call).
|
||||
|
||||
"""
|
||||
return _set_and_wait(states.POWER_ON, driver_info)
|
||||
|
||||
|
||||
def _power_off(driver_info):
|
||||
"""Turn the power OFF for this node.
|
||||
|
||||
:param driver_info: the xcat parameters for accessing a node.
|
||||
:returns: one of ironic.common.states POWER_OFF or ERROR.
|
||||
:raises: IPMIFailure on an error from ipmitool (from _power_status call).
|
||||
|
||||
"""
|
||||
return _set_and_wait(states.POWER_OFF, driver_info)
|
||||
|
||||
def _power_status(driver_info):
|
||||
"""Get the power status for a node.
|
||||
|
||||
:param driver_info: the xcat access parameters for a node.
|
||||
:returns: one of ironic.common.states POWER_OFF, POWER_ON or ERROR.
|
||||
:raises: IPMIFailure on an error from ipmitool.
|
||||
|
||||
"""
|
||||
cmd = "rpower"
|
||||
try:
|
||||
out_err = xcat_util.exec_xcatcmd(driver_info,cmd,'status')
|
||||
except Exception as e:
|
||||
LOG.warning(_("xcat rpower status failed for node %(node_id)s with "
|
||||
"error: %(error)s.")
|
||||
% {'node_id': driver_info['uuid'], 'error': e})
|
||||
|
||||
if out_err[0].split(' ')[1].strip() == "on":
|
||||
return states.POWER_ON
|
||||
elif out_err[0].split(' ')[1].strip() == "off":
|
||||
return states.POWER_OFF
|
||||
else:
|
||||
return states.ERROR
|
||||
|
||||
|
||||
class XcatPower(base.PowerInterface):
|
||||
|
||||
def __init__(self):
|
||||
try:
|
||||
check_timing_support()
|
||||
except OSError:
|
||||
raise exception.DriverLoadError(
|
||||
driver=self.__class__.__name__,
|
||||
reason="Unable to locate usable xcat command in "
|
||||
"the system path when checking xcat version")
|
||||
|
||||
def validate(self, task):
|
||||
"""Validate driver_info for xcat driver.
|
||||
|
||||
Check that node['driver_info'] contains IPMI credentials.
|
||||
|
||||
:param task: a TaskManager instance containing the node to act on.
|
||||
:raises: InvalidParameterValue if required ipmi parameters are missing.
|
||||
|
||||
"""
|
||||
driver_info = _parse_driver_info(task.node)
|
||||
try:
|
||||
chdef_node(driver_info)
|
||||
except exception:
|
||||
LOG.error(_("chdef xcat info error!"))
|
||||
|
||||
def get_power_state(self, task):
|
||||
"""Get the current power state of the task's node.
|
||||
|
||||
:param task: a TaskManager instance containing the node to act on.
|
||||
:returns: one of ironic.common.states POWER_OFF, POWER_ON or ERROR.
|
||||
|
||||
"""
|
||||
driver_info = _parse_driver_info(task.node)
|
||||
return _power_status(driver_info)
|
||||
|
||||
@task_manager.require_exclusive_lock
|
||||
def set_power_state(self, task, pstate):
|
||||
"""Turn the power on or off.
|
||||
|
||||
:param task: a TaskManager instance containing the node to act on.
|
||||
:param pstate: The desired power state, one of ironic.common.states
|
||||
POWER_ON, POWER_OFF.
|
||||
:raises: InvalidParameterValue if required ipmi parameters are missing
|
||||
or if an invalid power state was specified.
|
||||
:raises: PowerStateFailure if the power couldn't be set to pstate.
|
||||
|
||||
"""
|
||||
driver_info = _parse_driver_info(task.node)
|
||||
|
||||
if pstate == states.POWER_ON:
|
||||
state = _power_on(driver_info)
|
||||
elif pstate == states.POWER_OFF:
|
||||
state = _power_off(driver_info)
|
||||
else:
|
||||
raise exception.InvalidParameterValue(_("set_power_state called "
|
||||
"with invalid power state %s.") % pstate)
|
||||
if state != pstate:
|
||||
raise exception.PowerStateFailure(pstate=pstate)
|
||||
|
||||
@task_manager.require_exclusive_lock
|
||||
def reboot(self, task):
|
||||
"""Cycles the power to the task's node.
|
||||
|
||||
:param task: a TaskManager instance containing the node to act on.
|
||||
:raises: InvalidParameterValue if required ipmi parameters are missing.
|
||||
:raises: PowerStateFailure if the final state of the node is not
|
||||
POWER_ON.
|
||||
|
||||
"""
|
||||
driver_info = _parse_driver_info(task.node)
|
||||
_power_off(driver_info)
|
||||
state = _power_on(driver_info)
|
||||
|
||||
if state != states.POWER_ON:
|
||||
raise exception.PowerStateFailure(pstate=states.POWER_ON)
|
||||
|
||||
class VendorPassthru(base.VendorInterface):
|
||||
@task_manager.require_exclusive_lock
|
||||
def _set_boot_device(self, task, device, persistent=False):
|
||||
"""Set the boot device for a node.
|
||||
|
||||
:param task: a TaskManager instance.
|
||||
:param device: Boot device. One of [net, hd, cd, floppy, def, stat].
|
||||
:param persistent: Whether to set next-boot, or make the change
|
||||
permanent. Default: False.
|
||||
:raises: InvalidParameterValue if an invalid boot device is specified
|
||||
or if required ipmi parameters are missing.
|
||||
:raises: IPMIFailure on an error from ipmitool.
|
||||
|
||||
"""
|
||||
if device not in VALID_BOOT_DEVICES:
|
||||
raise exception.InvalidParameterValue(_(
|
||||
"Invalid boot device %s specified.") % device)
|
||||
cmd = "rsetboot"
|
||||
if persistent:
|
||||
cmd = cmd + " options=persistent"
|
||||
driver_info = _parse_driver_info(task.node)
|
||||
try:
|
||||
xcat_util.exec_xcatcmd(driver_info, cmd, device)
|
||||
# TODO(deva): validate (out, err) and add unit test for failure
|
||||
except xcat_exception.xCATCmdFailure:
|
||||
LOG.error(_("rsetboot %(node)s %(device)s"),{'node':driver_info['xcat_node]'],
|
||||
'device':device})
|
||||
|
||||
|
||||
def validate(self, task, **kwargs):
|
||||
""" run chdef command to config xcat node infomation """
|
||||
method = kwargs['method']
|
||||
if method == 'set_boot_device':
|
||||
device = kwargs.get('device')
|
||||
if device not in VALID_BOOT_DEVICES:
|
||||
raise exception.InvalidParameterValue(_(
|
||||
"Invalid boot device %s specified.") % device)
|
||||
else:
|
||||
raise exception.InvalidParameterValue(_(
|
||||
"Unsupported method (%s) passed to xcat driver.")
|
||||
% method)
|
||||
driver_info = _parse_driver_info(task.node)
|
||||
chdef_node(driver_info)
|
||||
|
||||
def vendor_passthru(self, task, **kwargs):
|
||||
method = kwargs['method']
|
||||
if method == 'set_boot_device':
|
||||
return self._set_boot_device(
|
||||
task,
|
||||
kwargs.get('device'),
|
||||
kwargs.get('persistent', False))
|
||||
|
||||
|
||||
class IPMIShellinaboxConsole(base.ConsoleInterface):
|
||||
"""A ConsoleInterface that uses ipmitool and shellinabox."""
|
||||
|
||||
def __init__(self):
|
||||
try:
|
||||
check_timing_support()
|
||||
except OSError:
|
||||
raise exception.DriverLoadError(
|
||||
driver=self.__class__.__name__,
|
||||
reason="Unable to locate usable xcat command in "
|
||||
"the system path when checking xcat version")
|
||||
|
||||
def validate(self, task):
|
||||
"""Validate the Node console info.
|
||||
|
||||
:param task: a task from TaskManager.
|
||||
:raises: InvalidParameterValue
|
||||
"""
|
||||
driver_info = _parse_driver_info(task.node)
|
||||
if not driver_info['xcat_node']:
|
||||
raise exception.InvalidParameterValue(_(
|
||||
"xcat node name not supplied to xcat baremetal driver."))
|
||||
if not driver_info['port']:
|
||||
raise exception.InvalidParameterValue(_(
|
||||
"IPMI terminal port not supplied to IPMI driver."))
|
||||
|
||||
def start_console(self, task):
|
||||
"""Start a remote console for the node."""
|
||||
driver_info = _parse_driver_info(task.node)
|
||||
|
||||
path = _console_pwfile_path(driver_info['uuid'])
|
||||
pw_file = console_utils.make_persistent_password_file(
|
||||
path, driver_info['password'])
|
||||
|
||||
ipmi_cmd = "/:%(uid)s:%(gid)s:HOME:ipmitool -H %(address)s" \
|
||||
" -I lanplus -U %(user)s -f %(pwfile)s" \
|
||||
% {'uid': os.getuid(),
|
||||
'gid': os.getgid(),
|
||||
'address': driver_info['address'],
|
||||
'user': driver_info['username'],
|
||||
'pwfile': pw_file}
|
||||
if CONF.debug:
|
||||
ipmi_cmd += " -v"
|
||||
ipmi_cmd += " sol activate"
|
||||
console_utils.start_shellinabox_console(driver_info['uuid'],
|
||||
driver_info['port'],
|
||||
ipmi_cmd)
|
||||
|
||||
def stop_console(self, task):
|
||||
"""Stop the remote console session for the node."""
|
||||
driver_info = _parse_driver_info(task.node)
|
||||
console_utils.stop_shellinabox_console(driver_info['uuid'])
|
||||
utils.unlink_without_raise(_console_pwfile_path(driver_info['uuid']))
|
||||
|
||||
def get_console(self, task):
|
||||
"""Get the type and connection information about the console."""
|
||||
driver_info = _parse_driver_info(task.node)
|
||||
url = console_utils.get_shellinabox_console_url(driver_info['port'])
|
||||
return {'type': 'shellinabox', 'url': url}
|
||||
@@ -1,110 +0,0 @@
|
||||
"""
|
||||
util for xcat baremetal driver
|
||||
exec_xcatcmd
|
||||
xcat_ssh to excute remote cmd
|
||||
"""
|
||||
import paramiko
|
||||
import time
|
||||
import socket
|
||||
from ironic.openstack.common import log as logging
|
||||
from oslo.config import cfg
|
||||
from ironic.drivers.modules import xcat_exception
|
||||
from ironic.common import utils
|
||||
|
||||
xcat_opts = [
|
||||
cfg.IntOpt('ssh_session_timeout',
|
||||
default=10,
|
||||
help='ssh session time'),
|
||||
cfg.FloatOpt('ssh_shell_wait',
|
||||
default=0.5,
|
||||
help='wait time for the ssh cmd excute'),
|
||||
cfg.IntOpt('ssh_buf_size',
|
||||
default=65535,
|
||||
help='Maximum size (in charactor) of cache for ssh, '
|
||||
'including those in use'),
|
||||
cfg.StrOpt('ssh_key',
|
||||
default=None,
|
||||
help='ssh private key to login '),
|
||||
cfg.StrOpt('ssh_key_pass',
|
||||
default=None,
|
||||
help='Maximum size (in charactor) of cache for ssh, '
|
||||
'including those in use'),
|
||||
]
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
CONF = cfg.CONF
|
||||
CONF.register_opts(xcat_opts, group='xcat')
|
||||
|
||||
LAST_CMD_TIME = {}
|
||||
|
||||
def xcat_ssh(ip,port,username,password,cmd):
|
||||
""" exec remote command with ssh """
|
||||
key =None
|
||||
if CONF.xcat.ssh_key:
|
||||
try:
|
||||
key=paramiko.RSAKey.from_private_key_file(CONF.xcat.ssh_key)
|
||||
except paramiko.PasswordRequiredException:
|
||||
if not CONF.ssh_key_pass:
|
||||
raise Exception.message("no pubkey password")
|
||||
key = paramiko.RSAKey.from_private_key_file(
|
||||
CONF.xcat.ssh_key, CONF.xcat.ssh_key.ssh_key_pass)
|
||||
s = paramiko.SSHClient()
|
||||
s.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||
try:
|
||||
s.connect(ip,port,username=username,password=password,pkey=key,
|
||||
timeout=CONF.xcat.ssh_session_timeout)
|
||||
except socket.timeout as e:
|
||||
LOG.error(_("Unable to connect to the ssh server Exception: %(exception)s"),
|
||||
{'exception': e})
|
||||
chan = s.invoke_shell()
|
||||
output = chan.recv(CONF.xcat.ssh_buf_size)
|
||||
while not output.rstrip().endswith('#') and not output.rstrip().endswith('$'):
|
||||
output = chan.recv(CONF.xcat.ssh_buf_size)
|
||||
for c in cmd :
|
||||
_xcat_ssh_exec(chan,c,password)
|
||||
|
||||
def _xcat_ssh_exec(chan,cmd,password):
|
||||
""" exec ssh command """
|
||||
chan.send(cmd + '\n')
|
||||
time.sleep(CONF.xcat.ssh_shell_wait)
|
||||
ret = chan.recv(CONF.xcat.ssh_buf_size)
|
||||
if 'password' in ret and ret.rstrip().endswith(':'):
|
||||
chan.send(password + '\n')
|
||||
output = chan.recv(CONF.xcat.ssh_buf_size)
|
||||
while not output.rstrip().endswith('#') and not output.rstrip().endswith('$'):
|
||||
output = chan.recv(CONF.xcat.ssh_buf_size)
|
||||
return output
|
||||
|
||||
def _tsplit(string, delimiters):
|
||||
""" Behaves str.split but supports multiple delimiters. """
|
||||
delimiters = tuple(delimiters)
|
||||
stack = [string,]
|
||||
for delimiter in delimiters:
|
||||
for i, substring in enumerate(stack):
|
||||
substack = substring.split(delimiter)
|
||||
stack.pop(i)
|
||||
for j, _substring in enumerate(substack):
|
||||
stack.insert(i+j, _substring)
|
||||
return stack
|
||||
|
||||
def exec_xcatcmd(driver_info, command, args):
|
||||
""" excute xcat cmd """
|
||||
cmd = [command,
|
||||
driver_info['xcat_node']
|
||||
]
|
||||
cmd.extend(args.split(" "))
|
||||
# NOTE: ensure that no communications are excuted more
|
||||
# often than once every min_command_interval seconds.
|
||||
time_till_next_poll = CONF.ipmi.min_command_interval - (
|
||||
time.time() - LAST_CMD_TIME.get(driver_info['xcat_node'], 0))
|
||||
if time_till_next_poll > 0:
|
||||
time.sleep(time_till_next_poll)
|
||||
try:
|
||||
out, err = utils.execute(*cmd)
|
||||
if err:
|
||||
raise xcat_exception.xCATCmdFailure(cmd=cmd,node=driver_info['xcat_node'],
|
||||
args=args)
|
||||
finally:
|
||||
LAST_CMD_TIME[driver_info['xcat_node']] = time.time()
|
||||
return out, err
|
||||
@@ -1,30 +0,0 @@
|
||||
"""
|
||||
XCATBaremetalDriver
|
||||
use xcat to deploy a baremetal machine
|
||||
"""
|
||||
|
||||
|
||||
from ironic.drivers import base
|
||||
from ironic.drivers.modules import ipmitool
|
||||
from ironic.drivers.modules import pxe
|
||||
from ironic.drivers.modules import xcat_pxe
|
||||
from ironic.drivers import utils
|
||||
from ironic.drivers.modules import xcat_rpower
|
||||
|
||||
|
||||
class XCATBaremetalDriver(base.BaseDriver):
|
||||
"""xCAT driver
|
||||
This driver implements the `core` functionality, combinding
|
||||
:class:`ironic.drivers.xcat_rpower.XcatPower` for power on/off and reboot with
|
||||
:class:`ironic.driver.xcat_pxe.PXEDeploy` for image deployment. Implementations are in
|
||||
those respective classes; this class is merely the glue between them.
|
||||
"""
|
||||
def __init__(self):
|
||||
self.power = xcat_rpower.XcatPower()
|
||||
self.console = ipmitool.IPMIShellinaboxConsole()
|
||||
self.deploy = xcat_pxe.PXEDeploy()
|
||||
self.pxe_vendor = pxe.VendorPassthru()
|
||||
self.ipmi_vendor = ipmitool.VendorPassthru()
|
||||
self.mapping = {'pass_deploy_info': self.pxe_vendor,
|
||||
'set_boot_device': self.ipmi_vendor}
|
||||
self.vendor = utils.MixinVendorInterface(self.mapping)
|
||||
@@ -1,33 +0,0 @@
|
||||
[DEFAULT]
|
||||
|
||||
# The list of modules to copy from oslo-incubator
|
||||
module=cliutils
|
||||
module=config.generator
|
||||
module=context
|
||||
module=db
|
||||
module=db.sqlalchemy
|
||||
module=db.sqlalchemy.migration_cli
|
||||
module=eventlet_backdoor
|
||||
module=excutils
|
||||
module=fileutils
|
||||
module=gettextutils
|
||||
module=importutils
|
||||
module=jsonutils
|
||||
module=local
|
||||
module=lockutils
|
||||
module=log
|
||||
module=loopingcall
|
||||
module=network_utils
|
||||
module=periodic_task
|
||||
module=policy
|
||||
module=processutils
|
||||
module=service
|
||||
module=strutils
|
||||
module=timeutils
|
||||
module=versionutils
|
||||
|
||||
# Tools
|
||||
|
||||
|
||||
# The base module to hold the copy of openstack.common
|
||||
base=ironic
|
||||
@@ -1,34 +0,0 @@
|
||||
[metadata]
|
||||
name = ironic
|
||||
version = 2014.2
|
||||
summary = OpenStack Bare Metal Provisioning
|
||||
description-file =
|
||||
README.rst
|
||||
author = chenglch
|
||||
author-email = chenglch@cn.ibm.com
|
||||
home-page = http://xcat.sf.net/
|
||||
classifier =
|
||||
Environment :: OpenStack
|
||||
Intended Audience :: Information Technology
|
||||
Intended Audience :: System Administrators
|
||||
License :: OSI Approved :: Apache Software License
|
||||
Operating System :: POSIX :: Linux
|
||||
Programming Language :: Python
|
||||
Programming Language :: Python :: 2
|
||||
Programming Language :: Python :: 2.7
|
||||
Programming Language :: Python :: 2.6
|
||||
|
||||
[files]
|
||||
packages =
|
||||
ironic
|
||||
|
||||
[entry_points]
|
||||
ironic.drivers =
|
||||
pxe_xcat = ironic.drivers.xcat:XCATBaremetalDriver
|
||||
|
||||
[pbr]
|
||||
autodoc_index_modules = True
|
||||
|
||||
[global]
|
||||
setup-hooks =
|
||||
pbr.hooks.setup_hook
|
||||
@@ -1,22 +0,0 @@
|
||||
hacking>=0.8.0,<0.9
|
||||
coverage>=3.6
|
||||
discover
|
||||
fixtures>=0.3.14
|
||||
mock>=1.0
|
||||
Babel>=1.3
|
||||
MySQL-python
|
||||
psycopg2
|
||||
python-ironicclient
|
||||
python-subunit>=0.0.18
|
||||
testrepository>=0.0.18
|
||||
testtools>=0.9.34
|
||||
|
||||
# Doc requirements
|
||||
sphinx>=1.1.2,!=1.2.0,<1.3
|
||||
sphinxcontrib-pecanwsme>=0.8
|
||||
oslosphinx
|
||||
|
||||
# Required for Nova unit tests in ironic/nova/tests/ and can be removed
|
||||
# once the driver code lands in Nova.
|
||||
http://tarballs.openstack.org/nova/nova-master.tar.gz#egg=nova
|
||||
mox>=0.5.3
|
||||
@@ -0,0 +1,15 @@
|
||||
AllCops:
|
||||
Excludes:
|
||||
- test/**
|
||||
- vendor/**
|
||||
|
||||
AlignParameters:
|
||||
Enabled: false
|
||||
Encoding:
|
||||
Enabled: false
|
||||
HashSyntax:
|
||||
Enabled: false
|
||||
LineLength:
|
||||
Enabled: false
|
||||
MethodLength:
|
||||
Max: 30
|
||||
@@ -0,0 +1,9 @@
|
||||
rvm:
|
||||
- 1.9.3
|
||||
- 2.0.0
|
||||
before_script:
|
||||
- bundle exec berks install
|
||||
script:
|
||||
- bundle exec foodcritic -f any . --tags ~FC007 --tags ~FC015 --tags ~FC023
|
||||
# - bundle exec rspec --color --format progress
|
||||
- bundle exec rubocop
|
||||
@@ -0,0 +1,7 @@
|
||||
site :opscode
|
||||
metadata
|
||||
|
||||
group :integration do
|
||||
cookbook 'apt', '~> 2.0'
|
||||
cookbook 'yum', '~> 2.0'
|
||||
end
|
||||
@@ -0,0 +1,198 @@
|
||||
apache2 Cookbook Changelog
|
||||
==========================
|
||||
This file is used to list changes made in each version of the apache2 cookbook.
|
||||
|
||||
v1.8.4
|
||||
------
|
||||
### Bug
|
||||
- **[COOK-3769](https://tickets.opscode.com/browse/COOK-3769)** - Fix a critical bug where the `apache_module` could not enable modules
|
||||
|
||||
|
||||
v1.8.2
|
||||
------
|
||||
### Bug
|
||||
- **[COOK-3766](https://tickets.opscode.com/browse/COOK-3766)** - Fix an issue where the `mod_ssl` recipe fails due to a missing attribute
|
||||
|
||||
|
||||
v1.8.0
|
||||
------
|
||||
### Bug
|
||||
- **[COOK-3680](https://tickets.opscode.com/browse/COOK-3680)** - Update template paths
|
||||
- **[COOK-3570](https://tickets.opscode.com/browse/COOK-3570)** - Apache cookbook breaks on RHEL / CentOS 6
|
||||
- **[COOK-2944](https://tickets.opscode.com/browse/COOK-2944)** - Fix foodcritic failures
|
||||
- **[COOK-2893](https://tickets.opscode.com/browse/COOK-2893)** - Improve mod_auth_openid recipe with guards and idempotency
|
||||
- **[COOK-2758](https://tickets.opscode.com/browse/COOK-2758)** - Fix use of non-existent attribute
|
||||
|
||||
### New Feature
|
||||
- **[COOK-3665](https://tickets.opscode.com/browse/COOK-3665)** - Add recipe for mod_userdir
|
||||
- **[COOK-3646](https://tickets.opscode.com/browse/COOK-3646)** - Add recipe for mod_cloudflare
|
||||
- **[COOK-3213](https://tickets.opscode.com/browse/COOK-3213)** - Add recipe for mod_info
|
||||
|
||||
### Improvement
|
||||
- **[COOK-3656](https://tickets.opscode.com/browse/COOK-3656)** - Parameterize apache2 binary
|
||||
- **[COOK-3562](https://tickets.opscode.com/browse/COOK-3562)** - Allow mod_proxy settings to be configured as attributes
|
||||
- **[COOK-3326](https://tickets.opscode.com/browse/COOK-3326)** - Fix default_test to use ServerTokens attribute
|
||||
- **[COOK-2635](https://tickets.opscode.com/browse/COOK-2635)** - Add support for SVG mime types
|
||||
- **[COOK-2598](https://tickets.opscode.com/browse/COOK-2598)** - FastCGI Module only works on Debian-based platforms
|
||||
- **[COOK-1984](https://tickets.opscode.com/browse/COOK-1984)** - Add option to configure the address apache listens to
|
||||
|
||||
|
||||
v1.7.0
|
||||
------
|
||||
### Improvement
|
||||
|
||||
- [COOK-3073]: make access.log location configurable per-platform
|
||||
- [COOK-3074]: don't hardcode the error.log location in the default site config
|
||||
- [COOK-3268]: don't hardcode DocumentRoot and cgi-bin locations in `default_site`
|
||||
|
||||
### New Feature
|
||||
|
||||
- [COOK-3184]: Add `mod_filter` recipe to Apache2-cookbook
|
||||
- [COOK-3236]: Add `mod_action` recipe to Apache2-cookbook
|
||||
|
||||
v1.6.6
|
||||
------
|
||||
1.6.4 had a missed step in the automated release, long live 1.6.6.
|
||||
|
||||
### Bug
|
||||
|
||||
- [COOK-3018]: apache2_module does duplicate delayed restart of apache2 service when conf = true
|
||||
- [COOK-3027]: Default site enable true, then false, does not disable default site
|
||||
- [COOK-3109]: fix apache lib_dir arch attribute regexp
|
||||
|
||||
v1.6.2
|
||||
------
|
||||
- [COOK-2535] - `mod_auth_openid` requires libtool to run autogen.sh
|
||||
- [COOK-2667] - Typo in usage documentation
|
||||
- [COOK-2461] - `apache2::mod_auth_openid` fails on some ubuntu systems
|
||||
- [COOK-2720] - Apache2 minitest helper function `ran_recipe` is not portable
|
||||
|
||||
v1.6.0
|
||||
------
|
||||
- [COOK-2372] - apache2 mpm_worker: add ServerLimit attribute (default to 16)
|
||||
|
||||
v1.5.0
|
||||
------
|
||||
The `mod_auth_openid` attributes are changed. The upstream maintainer deprecated the older release versions, and the source repository has releases available at specific SHA1SUM references. The new attribute, `node['apache']['mod_auth_openid']['ref']` is used to set this.
|
||||
|
||||
- [COOK-2198] - `apache::mod_auth_openid` compiles from source, but does not install make on debian/ubuntu
|
||||
- [COOK-2224] - version conflict between cucumber and other gems
|
||||
- [COOK-2248] - `apache2::mod_php5` uses `not_if` "which php" without ensuring package 'which' is installed
|
||||
- [COOK-2269] - Set allow list for mod_status incase external monitor scripts need
|
||||
- [COOK-2276] - cookbook apache2 documentation regarding listening ports doesn't match default attributes
|
||||
- [COOK-2296] - `mod_auth_openid` doesn't have tags/releases for the version I need for features and fixes
|
||||
- [COOK-2323] - Add Oracle linux support
|
||||
|
||||
v1.4.2
|
||||
------
|
||||
- [COOK-1721] - fix logrotate recipe
|
||||
|
||||
v1.4.0
|
||||
------
|
||||
- [COOK-1456] - iptables enhancements
|
||||
- [COOK-1473] - apache2 does not disable default site when setting "`default_site_enabled`" back to false
|
||||
- [COOK-1824] - the apache2 cookbook needs to specify which binary is used on rhel platform
|
||||
- [COOK-1916] - Download location wrong for apache2 `mod_auth_openid` >= 0.7
|
||||
- [COOK-1917] - Improve `mod_auth_openid` recipe to handle module upgrade more gracefully
|
||||
- [COOK-2029] - apache2 restarts on every run on RHEL and friends, generate-module-list on every run.
|
||||
- [COOK-2036] - apache2: Cookbook style
|
||||
|
||||
v1.3.2
|
||||
------
|
||||
- [COOK-1804] - fix `web_app` definition parameter so site can be disabled.
|
||||
|
||||
v1.3.0
|
||||
------
|
||||
- [COOK-1738] - Better configuration for `mod_include` and some overrides in `web_app` definition
|
||||
- [COOK-1470] - Change SSL Ciphers to Mitigate BEAST attack
|
||||
|
||||
v1.2.0
|
||||
------
|
||||
- [COOK-692] - delete package conf.d files in module recipes, for EL
|
||||
- [COOK-1693] - Foodcritic finding for unnecessary string interpolation
|
||||
- [COOK-1757] - platform_family and better style / usage practices
|
||||
|
||||
v1.1.16
|
||||
-------
|
||||
re-releasing as .16 due to error on tag 1.1.14
|
||||
|
||||
- [COOK-1466] - add `mod_auth_cas` recipe
|
||||
- [COOK-1609] - apache2 changes ports.conf twice per run when using apache2::mod_ssl
|
||||
|
||||
v1.1.12
|
||||
-------
|
||||
- [COOK-1436] - restore apache2 web_app definition
|
||||
- [COOK-1356] - allow ExtendedStatus via attribute
|
||||
- [COOK-1403] - add mod_fastcgi recipe
|
||||
|
||||
v1.1.10
|
||||
-------
|
||||
- [COOK-1315] - allow the default site to not be enabled
|
||||
- [COOK-1328] - cookbook tests (minitest, cucumber)
|
||||
|
||||
v1.1.8
|
||||
------
|
||||
- Some platforms with minimal installations that don't have perl won't have a `node['languages']['perl']` attribute, so remove the conditional and rely on the power of idempotence in the package resource.
|
||||
- [COOK-1214] - address foodcritic warnings
|
||||
- [COOK-1180] - add `mod_logio` and fix `mod_proxy`
|
||||
|
||||
v1.1.6
|
||||
------
|
||||
FreeBSD users: This release requires the `freebsd` cookbook. See README.md.
|
||||
|
||||
- [COOK-1025] - freebsd support in mod_php5 recipe
|
||||
|
||||
v1.1.4
|
||||
------
|
||||
- [COOK-1100] - support amazon linux
|
||||
|
||||
v1.1.2
|
||||
------
|
||||
- [COOK-996] - apache2::mod_php5 can cause PHP and module API mismatches
|
||||
- [COOK-1083] - return string for v_f_p and use correct value for default
|
||||
|
||||
v1.1.0
|
||||
------
|
||||
- [COOK-861] - Add `mod_perl` and apreq2
|
||||
- [COOK-941] - fix `mod_auth_openid` on FreeBSD
|
||||
- [COOK-1021] - add a commented-out LoadModule directive to keep apxs happy
|
||||
- [COOK-1022] - consistency for icondir attribute
|
||||
- [COOK-1023] - fix platform test for attributes
|
||||
- [COOK-1024] - fix a2enmod script so it runs cleanly on !bash
|
||||
- [COOK-1026] - fix `error_log` location on FreeBSD
|
||||
|
||||
v1.0.8
|
||||
------
|
||||
- COOK-548 - directory resource doesn't have backup parameter
|
||||
|
||||
v1.0.6
|
||||
------
|
||||
- COOK-915 - update to `mod_auth_openid` version 0.6, see __Recipes/mod_auth_openid__ below.
|
||||
- COOK-548 - Add support for FreeBSD.
|
||||
|
||||
v1.0.4
|
||||
------
|
||||
- COOK-859 - don't hardcode module paths
|
||||
|
||||
v1.0.2
|
||||
------
|
||||
- Tickets resolved in this release: COOK-788, COOK-782, COOK-780
|
||||
|
||||
v1.0.0
|
||||
------
|
||||
- Red Hat family support is greatly improved, all recipes except `god_monitor` converge.
|
||||
- Recipe `mod_auth_openid` now works on RHEL family distros
|
||||
- Recipe `mod_php5` will now remove config from package on RHEL family so it doesn't conflict with the cookbook's.
|
||||
- Added `php5.conf.erb` template for `mod_php5` recipe.
|
||||
- Create the run state directory for `mod_fcgid` to prevent a startup error on RHEL version 6.
|
||||
- New attribute `node['apache']['lib_dir']` to handle lib vs lib64 on RHEL family distributions.
|
||||
- New attribute `node['apache']['group']`.
|
||||
- Scientific Linux support added.
|
||||
- Use a file resource instead of the generate-module-list executed perl script on RHEL family.
|
||||
- "default" site can now be disabled.
|
||||
- web_app now has an "enable" parameter.
|
||||
- Support for dav_fs apache module.
|
||||
- Tickets resolved in this release: COOK-754, COOK-753, COOK-665, COOK-624, COOK-579, COOK-519, COOK-518
|
||||
- Fix node references in template for a2dissite
|
||||
- Use proper user and group attributes on files and templates.
|
||||
- Replace the anemic README.rdoc with this new and improved superpowered README.md :).
|
||||
@@ -0,0 +1,257 @@
|
||||
# Contributing to Opscode Cookbooks
|
||||
|
||||
We are glad you want to contribute to Opscode Cookbooks! The first
|
||||
step is the desire to improve the project.
|
||||
|
||||
You can find the answers to additional frequently asked questions
|
||||
[on the wiki](http://wiki.opscode.com/display/chef/How+to+Contribute).
|
||||
|
||||
You can find additional information about
|
||||
[contributing to cookbooks](http://wiki.opscode.com/display/chef/How+to+Contribute+to+Opscode+Cookbooks)
|
||||
on the wiki as well.
|
||||
|
||||
## Quick-contribute
|
||||
|
||||
* Create an account on our [bug tracker](http://tickets.opscode.com)
|
||||
* Sign our contributor agreement (CLA)
|
||||
[ online](https://secure.echosign.com/public/hostedForm?formid=PJIF5694K6L)
|
||||
(keep reading if you're contributing on behalf of your employer)
|
||||
* Create a ticket for your change on the
|
||||
[bug tracker](http://tickets.opscode.com)
|
||||
* Link to your patch as a rebased git branch or pull request from the
|
||||
ticket
|
||||
* Resolve the ticket as fixed
|
||||
|
||||
We regularly review contributions and will get back to you if we have
|
||||
any suggestions or concerns.
|
||||
|
||||
## The Apache License and the CLA/CCLA
|
||||
|
||||
Licensing is very important to open source projects, it helps ensure
|
||||
the software continues to be available under the terms that the author
|
||||
desired. Chef uses the Apache 2.0 license to strike a balance between
|
||||
open contribution and allowing you to use the software however you
|
||||
would like to.
|
||||
|
||||
The license tells you what rights you have that are provided by the
|
||||
copyright holder. It is important that the contributor fully
|
||||
understands what rights they are licensing and agrees to them.
|
||||
Sometimes the copyright holder isn't the contributor, most often when
|
||||
the contributor is doing work for a company.
|
||||
|
||||
To make a good faith effort to ensure these criteria are met, Opscode
|
||||
requires a Contributor License Agreement (CLA) or a Corporate
|
||||
Contributor License Agreement (CCLA) for all contributions. This is
|
||||
without exception due to some matters not being related to copyright
|
||||
and to avoid having to continually check with our lawyers about small
|
||||
patches.
|
||||
|
||||
It only takes a few minutes to complete a CLA, and you retain the
|
||||
copyright to your contribution.
|
||||
|
||||
You can complete our contributor agreement (CLA)
|
||||
[ online](https://secure.echosign.com/public/hostedForm?formid=PJIF5694K6L).
|
||||
If you're contributing on behalf of your employer, have your employer
|
||||
fill out our
|
||||
[Corporate CLA](https://secure.echosign.com/public/hostedForm?formid=PIE6C7AX856)
|
||||
instead.
|
||||
|
||||
## Ticket Tracker (JIRA)
|
||||
|
||||
The [ticket tracker](http://tickets.opscode.com) is the most important
|
||||
documentation for the code base. It provides significant historical
|
||||
information, such as:
|
||||
|
||||
* Which release a bug fix is included in
|
||||
* Discussion regarding the design and merits of features
|
||||
* Error output to aid in finding similar bugs
|
||||
|
||||
Each ticket should aim to fix one bug or add one feature.
|
||||
|
||||
## Using git
|
||||
|
||||
You can get a quick copy of the repository for this cookbook by
|
||||
running `git clone
|
||||
git://github.com/opscode-coobkooks/COOKBOOKNAME.git`.
|
||||
|
||||
For collaboration purposes, it is best if you create a Github account
|
||||
and fork the repository to your own account. Once you do this you will
|
||||
be able to push your changes to your Github repository for others to
|
||||
see and use.
|
||||
|
||||
If you have another repository in your GitHub account named the same
|
||||
as the cookbook, we suggest you suffix the repository with -cookbook.
|
||||
|
||||
### Branches and Commits
|
||||
|
||||
You should submit your patch as a git branch named after the ticket,
|
||||
such as COOK-1337. This is called a _topic branch_ and allows users to
|
||||
associate a branch of code with the ticket.
|
||||
|
||||
It is a best practice to have your commit message have a _summary
|
||||
line_ that includes the ticket number, followed by an empty line and
|
||||
then a brief description of the commit. This also helps other
|
||||
contributors understand the purpose of changes to the code.
|
||||
|
||||
[COOK-1757] - platform_family and style
|
||||
|
||||
* use platform_family for platform checking
|
||||
* update notifies syntax to "resource_type[resource_name]" instead of
|
||||
resources() lookup
|
||||
* COOK-692 - delete config files dropped off by packages in conf.d
|
||||
* dropped debian 4 support because all other platforms have the same
|
||||
values, and it is older than "old stable" debian release
|
||||
|
||||
Remember that not all users use Chef in the same way or on the same
|
||||
operating systems as you, so it is helpful to be clear about your use
|
||||
case and change so they can understand it even when it doesn't apply
|
||||
to them.
|
||||
|
||||
### Github and Pull Requests
|
||||
|
||||
All of Opscode's open source cookbook projects are available on
|
||||
[Github](http://www.github.com/opscode-cookbooks).
|
||||
|
||||
We don't require you to use Github, and we will even take patch diffs
|
||||
attached to tickets on the tracker. However Github has a lot of
|
||||
convenient features, such as being able to see a diff of changes
|
||||
between a pull request and the main repository quickly without
|
||||
downloading the branch.
|
||||
|
||||
If you do choose to use a pull request, please provide a link to the
|
||||
pull request from the ticket __and__ a link to the ticket from the
|
||||
pull request. Because pull requests only have two states, open and
|
||||
closed, we can't easily filter pull requests that are waiting for a
|
||||
reply from the author for various reasons.
|
||||
|
||||
### More information
|
||||
|
||||
Additional help with git is available on the
|
||||
[Working with Git](http://wiki.opscode.com/display/chef/Working+with+Git)
|
||||
wiki page.
|
||||
|
||||
## Functional and Unit Tests
|
||||
|
||||
This cookbook is set up to run tests under
|
||||
[Opscode's test-kitchen](https://github.com/opscode/test-kitchen). It
|
||||
uses minitest-chef to run integration tests after the node has been
|
||||
converged to verify that the state of the node.
|
||||
|
||||
Test kitchen should run completely without exception using the default
|
||||
[baseboxes provided by Opscode](https://github.com/opscode/bento).
|
||||
Because Test Kitchen creates VirtualBox machines and runs through
|
||||
every configuration in the Kitchenfile, it may take some time for
|
||||
these tests to complete.
|
||||
|
||||
If your changes are only for a specific recipe, run only its
|
||||
configuration with Test Kitchen. If you are adding a new recipe, or
|
||||
other functionality such as a LWRP or definition, please add
|
||||
appropriate tests and ensure they run with Test Kitchen.
|
||||
|
||||
If any don't pass, investigate them before submitting your patch.
|
||||
|
||||
Any new feature should have unit tests included with the patch with
|
||||
good code coverage to help protect it from future changes. Similarly,
|
||||
patches that fix a bug or regression should have a _regression test_.
|
||||
Simply put, this is a test that would fail without your patch but
|
||||
passes with it. The goal is to ensure this bug doesn't regress in the
|
||||
future. Consider a regular expression that doesn't match a certain
|
||||
pattern that it should, so you provide a patch and a test to ensure
|
||||
that the part of the code that uses this regular expression works as
|
||||
expected. Later another contributor may modify this regular expression
|
||||
in a way that breaks your use cases. The test you wrote will fail,
|
||||
signalling to them to research your ticket and use case and accounting
|
||||
for it.
|
||||
|
||||
If you need help writing tests, please ask on the Chef Developer's
|
||||
mailing list, or the #chef-hacking IRC channel.
|
||||
|
||||
## Code Review
|
||||
|
||||
Opscode regularly reviews code contributions and provides suggestions
|
||||
for improvement in the code itself or the implementation.
|
||||
|
||||
We find contributions by searching the ticket tracker for _resolved_
|
||||
tickets with a status of _fixed_. If we have feedback we will reopen
|
||||
the ticket and you should resolve it again when you've made the
|
||||
changes or have a response to our feedback. When we believe the patch
|
||||
is ready to be merged, we will tag the _Code Reviewed_ field with
|
||||
_Reviewed_.
|
||||
|
||||
Depending on the project, these tickets are then merged within a week
|
||||
or two, depending on the current release cycle.
|
||||
|
||||
## Release Cycle
|
||||
|
||||
The versioning for Opscode Cookbook projects is X.Y.Z.
|
||||
|
||||
* X is a major release, which may not be fully compatible with prior
|
||||
major releases
|
||||
* Y is a minor release, which adds both new features and bug fixes
|
||||
* Z is a patch release, which adds just bug fixes
|
||||
|
||||
A released version of a cookbook will end in an even number, e.g.
|
||||
"1.2.4" or "0.8.0". When development for the next version of the
|
||||
cookbook begins, the "Z" patch number is incremented to the next odd
|
||||
number, however the next release of the cookbook may be a major or
|
||||
minor incrementing version.
|
||||
|
||||
Releases of Opscode's cookbooks are usually announced on the Chef user
|
||||
mailing list. Releases of several cookbooks may be batched together
|
||||
and announced on the [Opscode Blog](http://www.opscode.com/blog).
|
||||
|
||||
## Working with the community
|
||||
|
||||
These resources will help you learn more about Chef and connect to
|
||||
other members of the Chef community:
|
||||
|
||||
* [chef](http://lists.opscode.com/sympa/info/chef) and
|
||||
[chef-dev](http://lists.opscode.com/sympa/info/chef-dev) mailing
|
||||
lists
|
||||
* #chef and #chef-hacking IRC channels on irc.freenode.net
|
||||
* [Community Cookbook site](http://community.opscode.com)
|
||||
* [Chef wiki](http://wiki.opscode.com/display/chef)
|
||||
* Opscode Chef [product page](http://www.opscode.com/chef)
|
||||
|
||||
|
||||
## Cookbook Contribution Do's and Don't's
|
||||
|
||||
Please do include tests for your contribution. If you need help, ask
|
||||
on the
|
||||
[chef-dev mailing list](http://lists.opscode.com/sympa/info/chef-dev)
|
||||
or the
|
||||
[#chef-hacking IRC channel](http://community.opscode.com/chat/chef-hacking).
|
||||
Not all platforms that a cookbook supports may be supported by Test
|
||||
Kitchen. Please provide evidence of testing your contribution if it
|
||||
isn't trivial so we don't have to duplicate effort in testing. Chef
|
||||
10.14+ "doc" formatted output is sufficient.
|
||||
|
||||
Please do indicate new platform (families) or platform versions in the
|
||||
commit message, and update the relevant ticket.
|
||||
|
||||
If a contribution adds new platforms or platform versions, indicate
|
||||
such in the body of the commit message(s), and update the relevant
|
||||
COOK ticket. When writing commit messages, it is helpful for others if
|
||||
you indicate the COOK ticket. For example:
|
||||
|
||||
git commit -m '[COOK-1041] - Updated pool resource to correctly
|
||||
delete.'
|
||||
|
||||
Please do use [foodcritic](http://acrmp.github.com/foodcritic) to
|
||||
lint-check the cookbook. Except FC007, it should pass all correctness
|
||||
rules. FC007 is okay as long as the dependent cookbooks are *required*
|
||||
for the default behavior of the cookbook, such as to support an
|
||||
uncommon platform, secondary recipe, etc.
|
||||
|
||||
Please do ensure that your changes do not break or modify behavior for
|
||||
other platforms supported by the cookbook. For example if your changes
|
||||
are for Debian, make sure that they do not break on CentOS.
|
||||
|
||||
Please do not modify the version number in the metadata.rb, Opscode
|
||||
will select the appropriate version based on the release cycle
|
||||
information above.
|
||||
|
||||
Please do not update the CHANGELOG.md for a new version. Not all
|
||||
changes to a cookbook may be merged and released in the same versions.
|
||||
Opscode will update the CHANGELOG.md when releasing a new version of
|
||||
the cookbook.
|
||||
@@ -0,0 +1,23 @@
|
||||
# source "https://rubygems.org"
|
||||
|
||||
# gem 'cucumber', '~> 1.2.0'
|
||||
# gem 'httparty', '~> 0.8.3'
|
||||
# gem 'minitest', '~> 3.0.0'
|
||||
# gem 'nokogiri', '~> 1.5.0'
|
||||
|
||||
# group :kitchen do
|
||||
# gem 'test-kitchen', '< 1.0'
|
||||
# end
|
||||
|
||||
|
||||
source 'https://rubygems.org'
|
||||
|
||||
gem 'berkshelf', '~> 2.0'
|
||||
gem 'chefspec', '~> 2.0'
|
||||
gem 'foodcritic', '~> 3.0'
|
||||
gem 'rubocop', '~> 0.12'
|
||||
|
||||
group :integration do
|
||||
gem 'test-kitchen', '~> 1.0.0.beta'
|
||||
gem 'kitchen-vagrant', '~> 0.11'
|
||||
end
|
||||
@@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
@@ -0,0 +1,586 @@
|
||||
apache2 Cookbook
|
||||
================
|
||||
[](http://travis-ci.org/opscode-cookbooks/apache2)
|
||||
|
||||
|
||||
This cookbook provides a complete Debian/Ubuntu style Apache HTTPD
|
||||
configuration. Non-Debian based distributions such as Red Hat/CentOS,
|
||||
ArchLinux and others supported by this cookbook will have a
|
||||
configuration that mimics Debian/Ubuntu style as it is easier to
|
||||
manage with Chef.
|
||||
|
||||
Debian-style Apache configuration uses scripts to manage modules and
|
||||
sites (vhosts). The scripts are:
|
||||
|
||||
* a2ensite
|
||||
* a2dissite
|
||||
* a2enmod
|
||||
* a2dismod
|
||||
|
||||
This cookbook ships with templates of these scripts for non
|
||||
Debian/Ubuntu platforms. The scripts are used in the __Definitions__
|
||||
below.
|
||||
|
||||
Requirements
|
||||
============
|
||||
|
||||
## Ohai and Chef:
|
||||
|
||||
* Ohai: 0.6.12+
|
||||
* Chef: 0.10.10+
|
||||
|
||||
As of v1.2.0, this cookbook makes use of `node['platform_family']` to
|
||||
simplify platform selection logic. This attribute was introduced in
|
||||
Ohai v0.6.12. The recipe methods were introduced in Chef v0.10.10. If
|
||||
you must run an older version of Chef or Ohai, use [version 1.1.16 of
|
||||
this cookbook](http://community.opscode.com/cookbooks/apache2/versions/1_1_16/downloads).
|
||||
|
||||
## Cookbooks:
|
||||
|
||||
This cookbook doesn't have direct dependencies on other cookbooks, as
|
||||
none are needed for the default recipe or the general use cases.
|
||||
|
||||
Depending on your OS configuration and security policy, you may need
|
||||
additional recipes or cookbooks for this cookbook's recipes to
|
||||
converge on the node. In particular, the following Operating System
|
||||
settings may affect the behavior of this cookbook:
|
||||
|
||||
* apt cache outdated
|
||||
* SELinux enabled
|
||||
* IPtables
|
||||
* Compile tools
|
||||
* 3rd party repositories
|
||||
|
||||
On Ubuntu/Debian, use Opscode's `apt` cookbook to ensure the package
|
||||
cache is updated so Chef can install packages, or consider putting
|
||||
apt-get in your bootstrap process or
|
||||
[knife bootstrap template](http://wiki.opscode.com/display/chef/Knife+Bootstrap).
|
||||
|
||||
On RHEL, SELinux is enabled by default. The `selinux` cookbook
|
||||
contains a `permissive` recipe that can be used to set SELinux to
|
||||
"Permissive" state. Otherwise, additional recipes need to be created
|
||||
by the user to address SELinux permissions.
|
||||
|
||||
The easiest but **certainly not ideal way** to deal with IPtables is
|
||||
to flush all rules. Opscode does provide an `iptables` cookbook but is
|
||||
migrating from the approach used there to a more robust solution
|
||||
utilizing a general "firewall" LWRP that would have an "iptables"
|
||||
provider. Alternately, you can use ufw, with Opscode's `ufw` and
|
||||
`firewall` cookbooks to set up rules. See those cookbooks' READMEs for
|
||||
documentation.
|
||||
|
||||
Build/compile tools may not be installed on the system by default.
|
||||
Some recipes (e.g., `apache2::mod_auth_openid`) build the module from
|
||||
source. Use Opscode's `build-essential` cookbook to get essential
|
||||
build packages installed.
|
||||
|
||||
On ArchLinux, if you are using the `apache2::mod_auth_openid` recipe,
|
||||
you also need the `pacman` cookbook for the `pacman_aur` LWRP. Put
|
||||
`recipe[pacman]` on the node's expanded run list (on the node or in a
|
||||
role). This is not an explicit dependency because it is only required
|
||||
for this single recipe and platform; the pacman default recipe
|
||||
performs `pacman -Sy` to keep pacman's package cache updated.
|
||||
|
||||
The `apache2::god_monitor` recipe uses a definition from the `god`
|
||||
cookbook. Include `recipe[god]` in the node's expanded run list to
|
||||
ensure that the cookbook is available to the node, and to set up `god`.
|
||||
|
||||
## Platforms:
|
||||
|
||||
The following platforms and versions are tested and supported using
|
||||
Opscode's [test-kitchen](http://github.com/opscode/test-kitchen).
|
||||
|
||||
* Ubuntu 10.04, 12.04
|
||||
* CentOS 5.8, 6.3
|
||||
|
||||
The following platform families are supported in the code, and are
|
||||
assumed to work based on the successful testing on Ubuntu and CentOS.
|
||||
|
||||
* Debian
|
||||
* Red Hat (rhel)
|
||||
* Fedora
|
||||
* Amazon Linux
|
||||
|
||||
The following platforms are also supported in the code, have been
|
||||
tested manually but are not tested under test-kitchen.
|
||||
|
||||
* SUSE/OpenSUSE
|
||||
* ArchLinux
|
||||
* FreeBSD
|
||||
|
||||
### Notes for RHEL Family:
|
||||
|
||||
On Red Hat Enterprise Linux and derivatives, the EPEL repository may
|
||||
be necessary to install packages used in certain recipes. The
|
||||
`apache2::default` recipe, however, does not require any additional
|
||||
repositories. Opscode's `yum` cookbook contains a recipe to add the
|
||||
EPEL repository. See __Examples__ for more information.
|
||||
|
||||
### Notes for FreeBSD:
|
||||
|
||||
The `apache2::mod_php5` recipe depends on the `freebsd` cookbook,
|
||||
which it uses to set the correct options for compiling the `php5` port
|
||||
from sources. You need to ensure the `freebsd` is in the expanded run
|
||||
list, or this recipe will fail. We don't set an explicit dependency
|
||||
because we feel the `freebsd` cookbook is something users would want
|
||||
on their nodes, and due to the generality of this cookbook we don't
|
||||
want additional specific dependencies.
|
||||
|
||||
Tests
|
||||
=====
|
||||
|
||||
This cookbook in the
|
||||
[source repository](https://github.com/opscode-cookbooks/apache2)
|
||||
contains minitest and cucumber tests. This is an initial proof of
|
||||
concept that will be fleshed out with more supporting infrastructure
|
||||
at a future time.
|
||||
|
||||
Please see the CONTRIBUTING file for information on how to add tests
|
||||
for your contributions.
|
||||
|
||||
Attributes
|
||||
==========
|
||||
|
||||
This cookbook uses many attributes, broken up into a few different
|
||||
kinds.
|
||||
|
||||
Platform specific
|
||||
-----------------
|
||||
|
||||
In order to support the broadest number of platforms, several
|
||||
attributes are determined based on the node's platform. See the
|
||||
attributes/default.rb file for default values in the case statement at
|
||||
the top of the file.
|
||||
|
||||
* `node['apache']['dir']` - Location for the Apache configuration
|
||||
* `node['apache']['log_dir']` - Location for Apache logs
|
||||
* `node['apache']['error_log']` - Location for the default error log
|
||||
* `node['apache']['access_log']` - Location for the default access log
|
||||
* `node['apache']['user']` - User Apache runs as
|
||||
* `node['apache']['group']` - Group Apache runs as
|
||||
* `node['apache']['binary']` - Apache httpd server daemon
|
||||
* `node['apache']['icondir']` - Location for icons
|
||||
* `node['apache']['cache_dir']` - Location for cached files used by Apache itself or recipes
|
||||
* `node['apache']['pid_file']` - Location of the PID file for Apache httpd
|
||||
* `node['apache']['lib_dir']` - Location for shared libraries
|
||||
* `node['apache']['default_site_enabled']` - Default site enabled. Default is false.
|
||||
* `node['apache']['ext_status']` - if true, enables ExtendedStatus for `mod_status`
|
||||
|
||||
General settings
|
||||
----------------
|
||||
|
||||
These are general settings used in recipes and templates. Default
|
||||
values are noted.
|
||||
|
||||
* `node['apache']['listen_addresses']` - Addresses that httpd should listen on. Default is any ("*").
|
||||
* `node['apache']['listen_ports']` - Ports that httpd should listen on. Default is port 80.
|
||||
* `node['apache']['contact']` - Value for ServerAdmin directive. Default "ops@example.com".
|
||||
* `node['apache']['timeout']` - Value for the Timeout directive. Default is 300.
|
||||
* `node['apache']['keepalive']` - Value for the KeepAlive directive. Default is On.
|
||||
* `node['apache']['keepaliverequests']` - Value for MaxKeepAliveRequests. Default is 100.
|
||||
* `node['apache']['keepalivetimeout']` - Value for the KeepAliveTimeout directive. Default is 5.
|
||||
* `node['apache']['default_modules']` - Array of module names. Can take "mod_FOO" or "FOO" as names, where FOO is the apache module, e.g. "`mod_status`" or "`status`".
|
||||
|
||||
The modules listed in `default_modules` will be included as recipes in `recipe[apache::default]`.
|
||||
|
||||
Prefork attributes
|
||||
------------------
|
||||
|
||||
Prefork attributes are used for tuning the Apache HTTPD prefork MPM
|
||||
configuration.
|
||||
|
||||
* `node['apache']['prefork']['startservers']` - initial number of server processes to start. Default is 16.
|
||||
* `node['apache']['prefork']['minspareservers']` - minimum number of spare server processes. Default 16.
|
||||
* `node['apache']['prefork']['maxspareservers']` - maximum number of spare server processes. Default 32.
|
||||
* `node['apache']['prefork']['serverlimit']` - upper limit on configurable server processes. Default 400.
|
||||
* `node['apache']['prefork']['maxclients']` - Maximum number of simultaneous connections.
|
||||
* `node['apache']['prefork']['maxrequestsperchild']` - Maximum number of request a child process will handle. Default 10000.
|
||||
|
||||
Worker attributes
|
||||
-----------------
|
||||
|
||||
Worker attributes are used for tuning the Apache HTTPD worker MPM
|
||||
configuration.
|
||||
|
||||
* `node['apache']['worker']['startservers']` - Initial number of server processes to start. Default 4
|
||||
* `node['apache']['worker']['serverlimit']` - upper limit on configurable server processes. Default 16.
|
||||
* `node['apache']['worker']['maxclients']` - Maximum number of simultaneous connections. Default 1024.
|
||||
* `node['apache']['worker']['minsparethreads']` - Minimum number of spare worker threads. Default 64
|
||||
* `node['apache']['worker']['maxsparethreads']` - Maximum number of spare worker threads. Default 192.
|
||||
* `node['apache']['worker']['maxrequestsperchild']` - Maximum number of requests a child process will handle.
|
||||
|
||||
mod\_auth\_openid attributes
|
||||
----------------------------
|
||||
|
||||
The following attributes are in the `attributes/mod_auth_openid.rb`
|
||||
file. Like all Chef attributes files, they are loaded as well, but
|
||||
they're logistically unrelated to the others, being specific to the
|
||||
`mod_auth_openid` recipe.
|
||||
|
||||
* `node['apache']['mod_auth_openid']['checksum']` - sha256sum of the tarball containing the source.
|
||||
* `node['apache']['mod_auth_openid']['ref']` - Any sha, tag, or branch found from https://github.com/bmuller/mod_auth_openid
|
||||
* `node['apache']['mod_auth_openid']['cache_dir']` - the cache directory is where the sqlite3 database is stored. It is separate so it can be managed as a directory resource.
|
||||
* `node['apache']['mod_auth_openid']['dblocation']` - filename of the sqlite3 database used for directive `AuthOpenIDDBLocation`, stored in the `cache_dir` by default.
|
||||
* `node['apache']['mod_auth_openid']['configure_flags']` - optional array of configure flags passed to the `./configure` step in the compilation of the module.
|
||||
|
||||
mod\_ssl attributes
|
||||
-------------------
|
||||
|
||||
* `node['apache']['mod_ssl']['cipher_suite']` - sets the
|
||||
SSLCiphersuite value to the specified string. The default is
|
||||
considered "sane" but you may need to change it for your local
|
||||
security policy, e.g. if you have PCI-DSS requirements. Additional
|
||||
commentary on the
|
||||
[original pull request](https://github.com/opscode-cookbooks/apache2/pull/15#commitcomment-1605406).
|
||||
|
||||
Recipes
|
||||
=======
|
||||
|
||||
Most of the recipes in the cookbook are for enabling Apache modules.
|
||||
Where additional configuration or behavior is used, it is documented
|
||||
below in more detail.
|
||||
|
||||
The following recipes merely enable the specified module: `mod_alias`,
|
||||
`mod_basic`, `mod_digest`, `mod_authn_file`, `mod_authnz_ldap`,
|
||||
`mod_authz_default`, `mod_authz_groupfile`, `mod_authz_host`,
|
||||
`mod_authz_user`, `mod_autoindex`, `mod_cgi`, `mod_dav_fs`,
|
||||
`mod_dav_svn`, `mod_deflate`, `mod_dir`, `mod_env`, `mod_expires`,
|
||||
`mod_headers`, `mod_ldap`, `mod_log_config`, `mod_mime`,
|
||||
`mod_negotiation`, `mod_proxy`, `mod_proxy_ajp`, `mod_proxy_balancer`,
|
||||
`mod_proxy_connect`, `mod_proxy_http`, `mod_python`, `mod_rewrite`,
|
||||
`mod_setenvif`, `mod_status`, `mod_wsgi`, `mod_xsendfile`.
|
||||
|
||||
On RHEL Family distributions, certain modules ship with a config file
|
||||
with the package. The recipes here may delete those configuration
|
||||
files to ensure they don't conflict with the settings from the
|
||||
cookbook, which will use per-module configuration in
|
||||
`/etc/httpd/mods-enabled`.
|
||||
|
||||
default
|
||||
-------
|
||||
|
||||
The default recipe does a number of things to set up Apache HTTPd. It
|
||||
also includes a number of modules based on the attribute
|
||||
`node['apache']['default_modules']` as recipes.
|
||||
|
||||
logrotate
|
||||
---------
|
||||
|
||||
Logrotate adds a logrotate entry for your apache2 logs. This recipe
|
||||
requires the `logrotate` cookbook; ensure that `recipe[logrotate]` is
|
||||
in the node's expanded run list.
|
||||
|
||||
mod\_auth\_cas
|
||||
--------------
|
||||
|
||||
This recipe installs the proper package and enables the `auth_cas`
|
||||
module. It can install from source or package. Package is the default,
|
||||
set the attribute `node['apache']['mod_auth_cas']['from_source']` to
|
||||
true to enable source installation. Modify the version to install by
|
||||
changing the attribute
|
||||
`node['apache']['mod_auth_cas']['source_revision']`. It is a version
|
||||
tag by default, but could be master, or another tag, or branch.
|
||||
|
||||
The module configuration is written out with the `CASCookiePath` set,
|
||||
otherwise an error loading the module may cause Apache to not start.
|
||||
|
||||
**Note**: This recipe does not work on EL 6 platforms unless
|
||||
epel-testing repository is enabled (outside the scope of this
|
||||
cookbook), or the package version 1.0.8.1-3.el6 or higher is otherwise
|
||||
available to the system due to this bug:
|
||||
|
||||
https://bugzilla.redhat.com/show_bug.cgi?format=multiple&id=708550
|
||||
|
||||
mod\_auth\_openid
|
||||
-----------------
|
||||
|
||||
**Changed via COOK-915**
|
||||
|
||||
This recipe compiles the module from source. In addition to
|
||||
`build-essential`, some other packages are included for installation
|
||||
like the GNU C++ compiler and development headers.
|
||||
|
||||
To use the module in your own cookbooks to authenticate systems using
|
||||
OpenIDs, specify an array of OpenIDs that are allowed to authenticate
|
||||
with the attribute `node['apache']['allowed_openids']`. Use the
|
||||
following in a vhost to protect with OpenID authentication:
|
||||
|
||||
AuthType OpenID require user <%= node['apache']['allowed_openids'].join(' ') %>
|
||||
AuthOpenIDDBLocation <%= node['apache']['mod_auth_openid']['dblocation'] %>
|
||||
|
||||
Change the DBLocation with the attribute as required; this file is in
|
||||
a different location than previous versions, see below. It should be a
|
||||
sane default for most platforms, though, see
|
||||
`attributes/mod_auth_openid.rb`.
|
||||
|
||||
### Changes from COOK-915:
|
||||
|
||||
* `AuthType OpenID` instead of `AuthOpenIDEnabled On`.
|
||||
* `require user` instead of `AuthOpenIDUserProgram`.
|
||||
* A bug(?) in `mod_auth_openid` causes it to segfault when attempting
|
||||
to update the database file if the containing directory is not
|
||||
writable by the HTTPD process owner (e.g., www-data), even if the
|
||||
file is writable. In order to not interfere with other settings from
|
||||
the default recipe in this cookbook, the db file is moved.
|
||||
|
||||
mod\_fastcgi
|
||||
------------
|
||||
|
||||
Install the fastcgi package and enable the module.
|
||||
|
||||
Only work on Debian/Ubuntu
|
||||
|
||||
mod\_fcgid
|
||||
----------
|
||||
|
||||
Installs the fcgi package and enables the module. Requires EPEL on
|
||||
RHEL family.
|
||||
|
||||
On RHEL family, this recipe will delete the fcgid.conf and on version
|
||||
6+, create the /var/run/httpd/mod_fcgid` directory, which prevents the
|
||||
emergency error:
|
||||
|
||||
[emerg] (2)No such file or directory: mod_fcgid: Can't create shared memory for size XX bytes
|
||||
|
||||
mod\_php5
|
||||
--------
|
||||
|
||||
Simply installs the appropriate package on Debian, Ubuntu and
|
||||
ArchLinux.
|
||||
|
||||
On Red Hat family distributions including Fedora, the php.conf that
|
||||
comes with the package is removed. On RHEL platforms less than v6, the
|
||||
`php53` package is used.
|
||||
|
||||
mod\_ssl
|
||||
--------
|
||||
|
||||
Besides installing and enabling `mod_ssl`, this recipe will append
|
||||
port 443 to the `node['apache']['listen_ports']` attribute array and
|
||||
update the ports.conf.
|
||||
|
||||
god\_monitor
|
||||
------------
|
||||
|
||||
Sets up a `god` monitor for Apache. External requirements are the
|
||||
`god` and `runit` cookbooks from Opscode. When using this recipe,
|
||||
include `recipe[god]` in the node's expanded run list to ensure the
|
||||
client downloads it; `god` depends on runit so that will also be
|
||||
downloaded.
|
||||
|
||||
**Note** This recipe is not tested under test-kitchen yet and is
|
||||
pending fix in COOK-744.
|
||||
|
||||
Definitions
|
||||
===========
|
||||
|
||||
The cookbook provides a few definitions. At some point in the future
|
||||
these definitions may be refactored into lightweight resources and
|
||||
providers as suggested by
|
||||
[foodcritic rule FC015](http://acrmp.github.com/foodcritic/#FC015).
|
||||
|
||||
apache\_conf
|
||||
------------
|
||||
|
||||
Sets up configuration file for an Apache module from a template. The
|
||||
template should be in the same cookbook where the definition is used.
|
||||
This is used by the `apache_module` definition and is not often used
|
||||
directly.
|
||||
|
||||
This will use a template resource to write the module's configuration
|
||||
file in the `mods-available` under the Apache configuration directory
|
||||
(`node['apache']['dir']`). This is a platform-dependent location. See
|
||||
__apache\_module__.
|
||||
|
||||
### Parameters:
|
||||
|
||||
* `name` - Name of the template. When used from the `apache_module`,
|
||||
it will use the same name as the module.
|
||||
|
||||
### Examples:
|
||||
|
||||
Create `#{node['apache']['dir']}/mods-available/alias.conf`.
|
||||
|
||||
apache_conf "alias"
|
||||
|
||||
apache\_module
|
||||
--------------
|
||||
|
||||
Enable or disable an Apache module in
|
||||
`#{node['apache']['dir']}/mods-available` by calling `a2enmod` or
|
||||
`a2dismod` to manage the symbolic link in
|
||||
`#{node['apache']['dir']}/mods-enabled`. If the module has a
|
||||
configuration file, a template should be created in the cookbook where
|
||||
the definition is used. See __Examples__.
|
||||
|
||||
### Parameters:
|
||||
|
||||
* `name` - Name of the module enabled or disabled with the `a2enmod` or `a2dismod` scripts.
|
||||
* `enable` - Default true, which uses `a2enmod` to enable the module. If false, the module will be disabled with `a2dismod`.
|
||||
* `conf` - Default false. Set to true if the module has a config file, which will use `apache_conf` for the file.
|
||||
* `filename` - specify the full name of the file, e.g.
|
||||
|
||||
### Examples:
|
||||
|
||||
Enable the ssl module, which also has a configuration template in `templates/default/mods/ssl.conf.erb`.
|
||||
|
||||
apache_module "ssl" do
|
||||
conf true
|
||||
end
|
||||
|
||||
Enable the php5 module, which has a different filename than the module default:
|
||||
|
||||
apache_module "php5" do
|
||||
filename "libphp5.so"
|
||||
end
|
||||
|
||||
Disable a module:
|
||||
|
||||
apache_module "disabled_module" do
|
||||
enable false
|
||||
end
|
||||
|
||||
See the recipes directory for many more examples of `apache_module`.
|
||||
|
||||
apache\_site
|
||||
------------
|
||||
|
||||
Enable or disable a VirtualHost in
|
||||
`#{node['apache']['dir']}/sites-available` by calling a2ensite or
|
||||
a2dissite to manage the symbolic link in
|
||||
`#{node['apache']['dir']}/sites-enabled`.
|
||||
|
||||
The template for the site must be managed as a separate resource. To
|
||||
combine the template with enabling a site, see `web_app`.
|
||||
|
||||
### Parameters:
|
||||
|
||||
* `name` - Name of the site.
|
||||
* `enable` - Default true, which uses `a2ensite` to enable the site. If false, the site will be disabled with `a2dissite`.
|
||||
|
||||
web\_app
|
||||
--------
|
||||
|
||||
Manage a template resource for a VirtualHost site, and enable it with
|
||||
`apache_site`. This is commonly done for managing web applications
|
||||
such as Ruby on Rails, PHP or Django, and the default behavior
|
||||
reflects that. However it is flexible.
|
||||
|
||||
This definition includes some recipes to make sure the system is
|
||||
configured to have Apache and some sane default modules:
|
||||
|
||||
* `apache2`
|
||||
* `apache2::mod_rewrite`
|
||||
* `apache2::mod_deflate`
|
||||
* `apache2::mod_headers`
|
||||
|
||||
It will then configure the template (see __Parameters__ and
|
||||
__Examples__ below), and enable or disable the site per the `enable`
|
||||
parameter.
|
||||
|
||||
### Parameters:
|
||||
|
||||
Current parameters used by the definition:
|
||||
|
||||
* `name` - The name of the site. The template will be written to
|
||||
`#{node['apache']['dir']}/sites-available/#{params['name']}.conf`
|
||||
* `cookbook` - Optional. Cookbook where the source template is. If
|
||||
this is not defined, Chef will use the named template in the
|
||||
cookbook where the definition is used.
|
||||
* `template` - Default `web_app.conf.erb`, source template file.
|
||||
* `enable` - Default true. Passed to the `apache_site` definition.
|
||||
|
||||
Additional parameters can be defined when the definition is called in
|
||||
a recipe, see __Examples__.
|
||||
|
||||
### Examples:
|
||||
|
||||
All parameters are passed into the template. You can use whatever you
|
||||
like. The apache2 cookbook comes with a `web_app.conf.erb` template as
|
||||
an example. The following parameters are used in the template:
|
||||
|
||||
* `server_name` - ServerName directive.
|
||||
* `server_aliases` - ServerAlias directive. Must be an array of aliases.
|
||||
* `docroot` - DocumentRoot directive.
|
||||
* `application_name` - Used in RewriteLog directive. Will be set to the `name` parameter.
|
||||
* `directory_index` - Allow overriding the default DirectoryIndex setting, optional
|
||||
* `directory_options` - Override Options on the docroot, for example to add parameters like Includes or Indexes, optional.
|
||||
* `allow_override` - Modify the AllowOverride directive on the docroot to support apps that need .htaccess to modify configuration or require authentication.
|
||||
|
||||
To use the default web_app, for example:
|
||||
|
||||
web_app "my_site" do
|
||||
server_name node['hostname']
|
||||
server_aliases [node['fqdn'], "my-site.example.com"]
|
||||
docroot "/srv/www/my_site"
|
||||
end
|
||||
|
||||
The parameters specified will be used as:
|
||||
|
||||
* `@params[:server_name]`
|
||||
* `@params[:server_aliases]`
|
||||
* `@params[:docroot]`
|
||||
|
||||
In the template. When you write your own, the `@` is significant.
|
||||
|
||||
For more information about Definitions and parameters, see the
|
||||
[Chef Wiki](http://wiki.opscode.com/display/chef/Definitions)
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
Using this cookbook is relatively straightforward. Add the desired
|
||||
recipes to the run list of a node, or create a role. Depending on your
|
||||
environment, you may have multiple roles that use different recipes
|
||||
from this cookbook. Adjust any attributes as desired. For example, to
|
||||
create a basic role for web servers that provide both HTTP and HTTPS:
|
||||
|
||||
% cat roles/webserver.rb
|
||||
name "webserver"
|
||||
description "Systems that serve HTTP and HTTPS"
|
||||
run_list(
|
||||
"recipe[apache2]",
|
||||
"recipe[apache2::mod_ssl]"
|
||||
)
|
||||
default_attributes(
|
||||
"apache" => {
|
||||
"listen_ports" => ["80", "443"]
|
||||
}
|
||||
)
|
||||
|
||||
For examples of using the definitions in your own recipes, see their
|
||||
respective sections above.
|
||||
|
||||
License and Authors
|
||||
===================
|
||||
|
||||
* Author:: Adam Jacob <adam@opscode.com>
|
||||
* Author:: Joshua Timberman <joshua@opscode.com>
|
||||
* Author:: Bryan McLellan <bryanm@widemile.com>
|
||||
* Author:: Dave Esposito <esposito@espolinux.corpnet.local>
|
||||
* Author:: David Abdemoulaie <github@hobodave.com>
|
||||
* Author:: Edmund Haselwanter <edmund@haselwanter.com>
|
||||
* Author:: Eric Rochester <err8n@virginia.edu>
|
||||
* Author:: Jim Browne <jbrowne@42lines.net>
|
||||
* Author:: Matthew Kent <mkent@magoazul.com>
|
||||
* Author:: Nathen Harvey <nharvey@customink.com>
|
||||
* Author:: Ringo De Smet <ringo.de.smet@amplidata.com>
|
||||
* Author:: Sean OMeara <someara@opscode.com>
|
||||
* Author:: Seth Chisamore <schisamo@opscode.com>
|
||||
* Author:: Gilles Devaux <gilles@peerpong.com>
|
||||
|
||||
* Copyright:: 2009-2012, Opscode, Inc
|
||||
* Copyright:: 2011, Atriso
|
||||
* Copyright:: 2011, CustomInk, LLC.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user