├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── create-image ├── create-image-manifest ├── create-iso ├── installerconfig └── triton-freebsd-guesttools ├── LICENSE ├── README.md ├── etc └── rc.d │ └── triton ├── lib └── smartdc │ ├── add-network-interface │ ├── common.lib │ ├── firstboot │ ├── format-secondary-disk │ ├── get-user-data │ ├── run-operator-script │ ├── run-user-script │ ├── set-hostname │ ├── set-root-authorized-keys │ ├── set-rootpassword │ └── triton └── usr ├── sbin ├── mdata-delete ├── mdata-get ├── mdata-list └── mdata-put └── share └── man └── man1 ├── mdata-delete.1 ├── mdata-get.1 ├── mdata-list.1 └── mdata-put.1 /.gitignore: -------------------------------------------------------------------------------- 1 | properties.yml 2 | user-data 3 | userscript.sh -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: bash 2 | addons: 3 | apt: 4 | sources: 5 | - debian-sid # Grab ShellCheck from the Debian repo 6 | packages: 7 | - shellcheck 8 | script: shellcheck -e SC2086 -s bash create-image create-image-manifest create-iso 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Mozilla Public License, version 2.0 2 | 3 | 1. Definitions 4 | 5 | 1.1. "Contributor" 6 | 7 | means each individual or legal entity that creates, contributes to the 8 | creation of, or owns Covered Software. 9 | 10 | 1.2. "Contributor Version" 11 | 12 | means the combination of the Contributions of others (if any) used by a 13 | Contributor and that particular Contributor's Contribution. 14 | 15 | 1.3. "Contribution" 16 | 17 | means Covered Software of a particular Contributor. 18 | 19 | 1.4. "Covered Software" 20 | 21 | means Source Code Form to which the initial Contributor has attached the 22 | notice in Exhibit A, the Executable Form of such Source Code Form, and 23 | Modifications of such Source Code Form, in each case including portions 24 | thereof. 25 | 26 | 1.5. "Incompatible With Secondary Licenses" 27 | means 28 | 29 | a. that the initial Contributor has attached the notice described in 30 | Exhibit B to the Covered Software; or 31 | 32 | b. that the Covered Software was made available under the terms of 33 | version 1.1 or earlier of the License, but not also under the terms of 34 | a Secondary License. 35 | 36 | 1.6. "Executable Form" 37 | 38 | means any form of the work other than Source Code Form. 39 | 40 | 1.7. "Larger Work" 41 | 42 | means a work that combines Covered Software with other material, in a 43 | separate file or files, that is not Covered Software. 44 | 45 | 1.8. "License" 46 | 47 | means this document. 48 | 49 | 1.9. "Licensable" 50 | 51 | means having the right to grant, to the maximum extent possible, whether 52 | at the time of the initial grant or subsequently, any and all of the 53 | rights conveyed by this License. 54 | 55 | 1.10. "Modifications" 56 | 57 | means any of the following: 58 | 59 | a. any file in Source Code Form that results from an addition to, 60 | deletion from, or modification of the contents of Covered Software; or 61 | 62 | b. any new file in Source Code Form that contains any Covered Software. 63 | 64 | 1.11. "Patent Claims" of a Contributor 65 | 66 | means any patent claim(s), including without limitation, method, 67 | process, and apparatus claims, in any patent Licensable by such 68 | Contributor that would be infringed, but for the grant of the License, 69 | by the making, using, selling, offering for sale, having made, import, 70 | or transfer of either its Contributions or its Contributor Version. 71 | 72 | 1.12. "Secondary License" 73 | 74 | means either the GNU General Public License, Version 2.0, the GNU Lesser 75 | General Public License, Version 2.1, the GNU Affero General Public 76 | License, Version 3.0, or any later versions of those licenses. 77 | 78 | 1.13. "Source Code Form" 79 | 80 | means the form of the work preferred for making modifications. 81 | 82 | 1.14. "You" (or "Your") 83 | 84 | means an individual or a legal entity exercising rights under this 85 | License. For legal entities, "You" includes any entity that controls, is 86 | controlled by, or is under common control with You. For purposes of this 87 | definition, "control" means (a) the power, direct or indirect, to cause 88 | the direction or management of such entity, whether by contract or 89 | otherwise, or (b) ownership of more than fifty percent (50%) of the 90 | outstanding shares or beneficial ownership of such entity. 91 | 92 | 93 | 2. License Grants and Conditions 94 | 95 | 2.1. Grants 96 | 97 | Each Contributor hereby grants You a world-wide, royalty-free, 98 | non-exclusive license: 99 | 100 | a. under intellectual property rights (other than patent or trademark) 101 | Licensable by such Contributor to use, reproduce, make available, 102 | modify, display, perform, distribute, and otherwise exploit its 103 | Contributions, either on an unmodified basis, with Modifications, or 104 | as part of a Larger Work; and 105 | 106 | b. under Patent Claims of such Contributor to make, use, sell, offer for 107 | sale, have made, import, and otherwise transfer either its 108 | Contributions or its Contributor Version. 109 | 110 | 2.2. Effective Date 111 | 112 | The licenses granted in Section 2.1 with respect to any Contribution 113 | become effective for each Contribution on the date the Contributor first 114 | distributes such Contribution. 115 | 116 | 2.3. Limitations on Grant Scope 117 | 118 | The licenses granted in this Section 2 are the only rights granted under 119 | this License. No additional rights or licenses will be implied from the 120 | distribution or licensing of Covered Software under this License. 121 | Notwithstanding Section 2.1(b) above, no patent license is granted by a 122 | Contributor: 123 | 124 | a. for any code that a Contributor has removed from Covered Software; or 125 | 126 | b. for infringements caused by: (i) Your and any other third party's 127 | modifications of Covered Software, or (ii) the combination of its 128 | Contributions with other software (except as part of its Contributor 129 | Version); or 130 | 131 | c. under Patent Claims infringed by Covered Software in the absence of 132 | its Contributions. 133 | 134 | This License does not grant any rights in the trademarks, service marks, 135 | or logos of any Contributor (except as may be necessary to comply with 136 | the notice requirements in Section 3.4). 137 | 138 | 2.4. Subsequent Licenses 139 | 140 | No Contributor makes additional grants as a result of Your choice to 141 | distribute the Covered Software under a subsequent version of this 142 | License (see Section 10.2) or under the terms of a Secondary License (if 143 | permitted under the terms of Section 3.3). 144 | 145 | 2.5. Representation 146 | 147 | Each Contributor represents that the Contributor believes its 148 | Contributions are its original creation(s) or it has sufficient rights to 149 | grant the rights to its Contributions conveyed by this License. 150 | 151 | 2.6. Fair Use 152 | 153 | This License is not intended to limit any rights You have under 154 | applicable copyright doctrines of fair use, fair dealing, or other 155 | equivalents. 156 | 157 | 2.7. Conditions 158 | 159 | Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in 160 | Section 2.1. 161 | 162 | 163 | 3. Responsibilities 164 | 165 | 3.1. Distribution of Source Form 166 | 167 | All distribution of Covered Software in Source Code Form, including any 168 | Modifications that You create or to which You contribute, must be under 169 | the terms of this License. You must inform recipients that the Source 170 | Code Form of the Covered Software is governed by the terms of this 171 | License, and how they can obtain a copy of this License. You may not 172 | attempt to alter or restrict the recipients' rights in the Source Code 173 | Form. 174 | 175 | 3.2. Distribution of Executable Form 176 | 177 | If You distribute Covered Software in Executable Form then: 178 | 179 | a. such Covered Software must also be made available in Source Code Form, 180 | as described in Section 3.1, and You must inform recipients of the 181 | Executable Form how they can obtain a copy of such Source Code Form by 182 | reasonable means in a timely manner, at a charge no more than the cost 183 | of distribution to the recipient; and 184 | 185 | b. You may distribute such Executable Form under the terms of this 186 | License, or sublicense it under different terms, provided that the 187 | license for the Executable Form does not attempt to limit or alter the 188 | recipients' rights in the Source Code Form under this License. 189 | 190 | 3.3. Distribution of a Larger Work 191 | 192 | You may create and distribute a Larger Work under terms of Your choice, 193 | provided that You also comply with the requirements of this License for 194 | the Covered Software. If the Larger Work is a combination of Covered 195 | Software with a work governed by one or more Secondary Licenses, and the 196 | Covered Software is not Incompatible With Secondary Licenses, this 197 | License permits You to additionally distribute such Covered Software 198 | under the terms of such Secondary License(s), so that the recipient of 199 | the Larger Work may, at their option, further distribute the Covered 200 | Software under the terms of either this License or such Secondary 201 | License(s). 202 | 203 | 3.4. Notices 204 | 205 | You may not remove or alter the substance of any license notices 206 | (including copyright notices, patent notices, disclaimers of warranty, or 207 | limitations of liability) contained within the Source Code Form of the 208 | Covered Software, except that You may alter any license notices to the 209 | extent required to remedy known factual inaccuracies. 210 | 211 | 3.5. Application of Additional Terms 212 | 213 | You may choose to offer, and to charge a fee for, warranty, support, 214 | indemnity or liability obligations to one or more recipients of Covered 215 | Software. However, You may do so only on Your own behalf, and not on 216 | behalf of any Contributor. You must make it absolutely clear that any 217 | such warranty, support, indemnity, or liability obligation is offered by 218 | You alone, and You hereby agree to indemnify every Contributor for any 219 | liability incurred by such Contributor as a result of warranty, support, 220 | indemnity or liability terms You offer. You may include additional 221 | disclaimers of warranty and limitations of liability specific to any 222 | jurisdiction. 223 | 224 | 4. Inability to Comply Due to Statute or Regulation 225 | 226 | If it is impossible for You to comply with any of the terms of this License 227 | with respect to some or all of the Covered Software due to statute, 228 | judicial order, or regulation then You must: (a) comply with the terms of 229 | this License to the maximum extent possible; and (b) describe the 230 | limitations and the code they affect. Such description must be placed in a 231 | text file included with all distributions of the Covered Software under 232 | this License. Except to the extent prohibited by statute or regulation, 233 | such description must be sufficiently detailed for a recipient of ordinary 234 | skill to be able to understand it. 235 | 236 | 5. Termination 237 | 238 | 5.1. The rights granted under this License will terminate automatically if You 239 | fail to comply with any of its terms. However, if You become compliant, 240 | then the rights granted under this License from a particular Contributor 241 | are reinstated (a) provisionally, unless and until such Contributor 242 | explicitly and finally terminates Your grants, and (b) on an ongoing 243 | basis, if such Contributor fails to notify You of the non-compliance by 244 | some reasonable means prior to 60 days after You have come back into 245 | compliance. Moreover, Your grants from a particular Contributor are 246 | reinstated on an ongoing basis if such Contributor notifies You of the 247 | non-compliance by some reasonable means, this is the first time You have 248 | received notice of non-compliance with this License from such 249 | Contributor, and You become compliant prior to 30 days after Your receipt 250 | of the notice. 251 | 252 | 5.2. If You initiate litigation against any entity by asserting a patent 253 | infringement claim (excluding declaratory judgment actions, 254 | counter-claims, and cross-claims) alleging that a Contributor Version 255 | directly or indirectly infringes any patent, then the rights granted to 256 | You by any and all Contributors for the Covered Software under Section 257 | 2.1 of this License shall terminate. 258 | 259 | 5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user 260 | license agreements (excluding distributors and resellers) which have been 261 | validly granted by You or Your distributors under this License prior to 262 | termination shall survive termination. 263 | 264 | 6. Disclaimer of Warranty 265 | 266 | Covered Software is provided under this License on an "as is" basis, 267 | without warranty of any kind, either expressed, implied, or statutory, 268 | including, without limitation, warranties that the Covered Software is free 269 | of defects, merchantable, fit for a particular purpose or non-infringing. 270 | The entire risk as to the quality and performance of the Covered Software 271 | is with You. Should any Covered Software prove defective in any respect, 272 | You (not any Contributor) assume the cost of any necessary servicing, 273 | repair, or correction. This disclaimer of warranty constitutes an essential 274 | part of this License. No use of any Covered Software is authorized under 275 | this License except under this disclaimer. 276 | 277 | 7. Limitation of Liability 278 | 279 | Under no circumstances and under no legal theory, whether tort (including 280 | negligence), contract, or otherwise, shall any Contributor, or anyone who 281 | distributes Covered Software as permitted above, be liable to You for any 282 | direct, indirect, special, incidental, or consequential damages of any 283 | character including, without limitation, damages for lost profits, loss of 284 | goodwill, work stoppage, computer failure or malfunction, or any and all 285 | other commercial damages or losses, even if such party shall have been 286 | informed of the possibility of such damages. This limitation of liability 287 | shall not apply to liability for death or personal injury resulting from 288 | such party's negligence to the extent applicable law prohibits such 289 | limitation. Some jurisdictions do not allow the exclusion or limitation of 290 | incidental or consequential damages, so this exclusion and limitation may 291 | not apply to You. 292 | 293 | 8. Litigation 294 | 295 | Any litigation relating to this License may be brought only in the courts 296 | of a jurisdiction where the defendant maintains its principal place of 297 | business and such litigation shall be governed by laws of that 298 | jurisdiction, without reference to its conflict-of-law provisions. Nothing 299 | in this Section shall prevent a party's ability to bring cross-claims or 300 | counter-claims. 301 | 302 | 9. Miscellaneous 303 | 304 | This License represents the complete agreement concerning the subject 305 | matter hereof. If any provision of this License is held to be 306 | unenforceable, such provision shall be reformed only to the extent 307 | necessary to make it enforceable. Any law or regulation which provides that 308 | the language of a contract shall be construed against the drafter shall not 309 | be used to construe this License against a Contributor. 310 | 311 | 312 | 10. Versions of the License 313 | 314 | 10.1. New Versions 315 | 316 | Mozilla Foundation is the license steward. Except as provided in Section 317 | 10.3, no one other than the license steward has the right to modify or 318 | publish new versions of this License. Each version will be given a 319 | distinguishing version number. 320 | 321 | 10.2. Effect of New Versions 322 | 323 | You may distribute the Covered Software under the terms of the version 324 | of the License under which You originally received the Covered Software, 325 | or under the terms of any subsequent version published by the license 326 | steward. 327 | 328 | 10.3. Modified Versions 329 | 330 | If you create software not governed by this License, and you want to 331 | create a new license for such software, you may create and use a 332 | modified version of this License if you rename the license and remove 333 | any references to the name of the license steward (except to note that 334 | such modified license differs from this License). 335 | 336 | 10.4. Distributing Source Code Form that is Incompatible With Secondary 337 | Licenses If You choose to distribute Source Code Form that is 338 | Incompatible With Secondary Licenses under the terms of this version of 339 | the License, the notice described in Exhibit B of this License must be 340 | attached. 341 | 342 | Exhibit A - Source Code Form License Notice 343 | 344 | This Source Code Form is subject to the 345 | terms of the Mozilla Public License, v. 346 | 2.0. If a copy of the MPL was not 347 | distributed with this file, You can 348 | obtain one at 349 | http://mozilla.org/MPL/2.0/. 350 | 351 | If it is not possible or desirable to put the notice in a particular file, 352 | then You may include the notice in a location (such as a LICENSE file in a 353 | relevant directory) where a recipient would be likely to look for such a 354 | notice. 355 | 356 | You may add additional accurate notices of copyright ownership. 357 | 358 | Exhibit B - "Incompatible With Secondary Licenses" Notice 359 | 360 | This Source Code Form is "Incompatible 361 | With Secondary Licenses", as defined by 362 | the Mozilla Public License, v. 2.0. 363 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # freebsd-kvm-image-builder 2 | 3 | This repo creates a custom FreeBSD install ISO and a KVM image for use in SmartOS and Triton. 4 | 5 | ## Requirements 6 | 7 | This must be run on a FreeBSD machine or VirtualMachine. 8 | 9 | ## Setup 10 | 11 | The following packages are required: 12 | 13 | ``` 14 | pkg install -y bash rsync cdrtools 15 | ``` 16 | 17 | ## Usage 18 | 19 | To build a custom ISO, run the `create-iso` script: 20 | 21 | 22 | ``` 23 | ./create-iso -r -m -p -i -c -d -M -l -f 24 | ``` 25 | 26 | see `./create-iso -h` for usage 27 | 28 | This will download an ISO, created a customized layout with installerconfig, install the Triton guesttools then build the custom ISO. 29 | 30 | To build the FreeBSD KVM image run the `create-image` script: 31 | 32 | ``` 33 | ./create-image -i -n -d -u -o -p -m NETMASK -g -v -U 34 | ``` 35 | 36 | see `./create-image -h` for usage 37 | -------------------------------------------------------------------------------- /create-image: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Copyright (c) 2016 Joyent Inc., All rights reserved. 4 | # 5 | 6 | if [[ -n "$TRACE" ]]; then 7 | export PS4='[\D{%FT%TZ}] ${BASH_SOURCE}:${LINENO}: ${FUNCNAME[0]:+${FUNCNAME[0]}(): }' 8 | set -o xtrace 9 | fi 10 | 11 | set -euo pipefail 12 | IFS=$'\n\t' 13 | 14 | ISO= 15 | IMAGE_NAME= 16 | OWNER_UUID= 17 | DESC= 18 | HOMEPAGE= 19 | 20 | IP= 21 | NETMASK= 22 | GATEWAY= 23 | VLAN_ID= 24 | NETWORK_UUID= 25 | 26 | BLANK_MANIFEST=blank.json 27 | BUILD_DATE=$(date +%Y%m%d) 28 | 29 | VM_UUID= 30 | 31 | usage() { 32 | cat < -n -d -u -o -p -m NETMASK -g -v -U 38 | 39 | Example: 40 | $0 -i binary.iso -n freebsd-11 -d "FreeBSD 11.0 64-bit image with just essential packages installed. Ideal for users who are comfortable with setting up their own environment and tools." -u https://docs.joyent.com/images/kvm/freebsd -o 00000000-0000-0000-0000-000000000000 -p 192.0.2.21 -m -g -v -U 41 | 42 | OPTIONS: 43 | -i The ISO 44 | -n The name of the image as it would appear in the manifest 45 | -d The description of the image 46 | -u The homepage URL for the image 47 | -o The onwer UUID for the blank VM 48 | -p The IP address for the blank VM 49 | -m The netmask for the blank VM 50 | -g The gateway for the blank VM 51 | -v The vlan ID for blank VM 52 | -U The Network UUID for the blank vm 53 | -h Show this message 54 | 55 | EOF 56 | } 57 | 58 | while getopts "hi:n:d:u:o:p:m:g:v:U:" OPTION 59 | do 60 | case $OPTION in 61 | h) 62 | usage 63 | exit 1 64 | ;; 65 | i) 66 | ISO=${OPTARG} 67 | ;; 68 | n) 69 | IMAGE_NAME=${OPTARG} 70 | ;; 71 | d) 72 | DESC=${OPTARG} 73 | ;; 74 | u) 75 | HOMEPAGE=${OPTARG} 76 | ;; 77 | o) 78 | OWNER_UUID=${OPTARG} 79 | ;; 80 | p) 81 | IP=${OPTARG} 82 | ;; 83 | m) 84 | NETMASK=${OPTARG} 85 | ;; 86 | g) 87 | GATEWAY=${OPTARG} 88 | ;; 89 | v) 90 | VLAN_ID=${OPTARG} 91 | ;; 92 | U) 93 | NETWORK_UUID=${OPTARG} 94 | ;; 95 | ?) 96 | usage 97 | exit 1 98 | ;; 99 | esac 100 | done 101 | 102 | if [[ -z ${ISO} || -z ${IMAGE_NAME} || -z ${DESC} || -z ${HOMEPAGE} \ 103 | || -z ${OWNER_UUID} || -z ${IP} || -z ${NETMASK} || -z ${VLAN_ID} \ 104 | || -z ${NETWORK_UUID} || -z ${GATEWAY} ]]; then 105 | 106 | echo "FATAL: All of -i, -n, -d, -u, -o, -p, -m, -g, -v, and -U are required." 107 | usage 108 | exit 1 109 | fi 110 | 111 | # The manifest for the blank VM, saved as blank.json 112 | cat << MANIFEST > $BLANK_MANIFEST 113 | { 114 | "brand": "kvm", 115 | "alias": "$IMAGE_NAME", 116 | "hostname": "$IMAGE_NAME", 117 | "autoboot": false, 118 | "ram": 1024, 119 | "vcpus": 2, 120 | "cpu_type": "host", 121 | "disk_driver": "virtio", 122 | "nic_driver": "virtio", 123 | "max_physical_memory": 2048, 124 | "quota": 10, 125 | "disks": [ 126 | { 127 | "boot": true, 128 | "model": "virtio", 129 | "size": 10240 130 | } 131 | ], 132 | "owner_uuid": "$OWNER_UUID", 133 | "resolvers": [ 134 | "8.8.8.8", 135 | "8.8.4.4" 136 | ], 137 | "nics": [ 138 | { 139 | "interface": "net0", 140 | "nic_tag": "external", 141 | "ip": "$IP", 142 | "primary": "true", 143 | "netmask": "$NETMASK", 144 | "gateway": "$GATEWAY", 145 | "vlan_id": $VLAN_ID, 146 | "model": "virtio", 147 | "network_uuid": "$NETWORK_UUID" 148 | } 149 | ] 150 | } 151 | MANIFEST 152 | 153 | check_for_blank() { 154 | echo "==> Checking for existing blank $IMAGE_NAME VM." 155 | set +e 156 | blank=$(pfexec vmadm list | grep $IMAGE_NAME) 157 | 158 | if [[ $? -eq 0 ]]; then 159 | echo "==> Blank VM $IMAGE_NAME found:" 160 | echo "==> $blank" 161 | echo -n "==> Deleting..." 162 | blank_uuid=$(echo $blank | cut -f1 -d ' ') 163 | pfexec vmadm delete $blank_uuid 164 | echo "done!" 165 | echo "==> Sleeping for 5 seconds before we continue." 166 | sleep 5 167 | else 168 | echo "No Blank VM $IMAGE_NAME found. It's safe to create a new one." 169 | fi 170 | set -e 171 | echo "==>" 172 | } 173 | 174 | create_blank() { 175 | echo -n "==> Creating blank $IMAGE_NAME VM and getting VM_UUID..." 176 | VM_UUID=$(pfexec vmadm create -f $BLANK_MANIFEST 2>&1 | awk '{print $4;}') 177 | echo "done!" 178 | echo "==> VM_UUID is ${VM_UUID}" 179 | echo "==>" 180 | } 181 | 182 | copy_iso() { 183 | echo -n "==> Copying $ISO to /zones/${VM_UUID}/root/..." 184 | pfexec cp $ISO /zones/${VM_UUID}/root/ 185 | echo "done!" 186 | echo "==>" 187 | } 188 | 189 | start_blank() { 190 | echo "==> Starting ${VM_UUID} with cdrom=/$ISO:" 191 | pfexec vmadm start ${VM_UUID} order=cd,once=d cdrom=/$ISO,ide 192 | echo "==>" 193 | } 194 | 195 | get_VNC() { 196 | echo "==> Getting VNC info for ${VM_UUID}:" 197 | host=$(pfexec vmadm info ${VM_UUID} vnc 2>&1 | json -a vnc.host) 198 | port=$(pfexec vmadm info ${VM_UUID} vnc 2>&1 | json -a vnc.port) 199 | echo "==> Host: $host" 200 | echo "==> Port: $port" 201 | echo "==>" 202 | } 203 | 204 | check_state() { 205 | echo -n "==> Checking state of '$IMAGE_NAME' VM to ensure it's stopped before we proceed..." 206 | STATE="running" 207 | while [[ $STATE != "stopped" ]]; do 208 | STATE=$(pfexec vmadm get ${VM_UUID} | json -a state) 209 | echo -n "." 210 | sleep 1 211 | done 212 | echo "ready!" 213 | echo "==> The '$IMAGE_NAME' VM is stopped. Sleping for 15 seconds before we continue." 214 | sleep 15 215 | echo "==>" 216 | } 217 | 218 | snapshot() { 219 | echo "==> Creating snapshot..." 220 | zfs snapshot zones/${VM_UUID}-disk0@dataset-${BUILD_DATE} 221 | echo "==> done!" 222 | echo "==>" 223 | } 224 | 225 | create_file() { 226 | echo "==> Creating image file..." 227 | zfs send zones/${VM_UUID}-disk0@dataset-${BUILD_DATE} | gzip -9 > ${IMAGE_NAME}-${BUILD_DATE}.zfs.gz 228 | echo "==> done!" 229 | echo "==>" 230 | } 231 | 232 | create_manifest() { 233 | echo "==> Creating manifest file..." 234 | ./create-image-manifest -f ${IMAGE_NAME}-${BUILD_DATE}.zfs.gz -n ${IMAGE_NAME} -s 10240 -v ${BUILD_DATE} -d "$DESC" -h $HOMEPAGE -o bsd > ${IMAGE_NAME}-${BUILD_DATE}.json 235 | echo "==> done!" 236 | echo "==>" 237 | } 238 | 239 | show_image_files() { 240 | echo "*** Image creation complete ***" 241 | echo "==> Image files:" 242 | echo "${IMAGE_NAME}-${BUILD_DATE}.json" 243 | echo "${IMAGE_NAME}-${BUILD_DATE}.zfs.gz" 244 | echo "" 245 | } 246 | 247 | clean_up() { 248 | rm -rf blank.json 249 | echo "==> Deleting blank $IMAGE_NAME VM: ${VM_UUID}" 250 | pfexec vmadm delete ${VM_UUID} 251 | } 252 | 253 | # MAIN 254 | 255 | echo "*** Starting image creation process! ***" 256 | 257 | check_for_blank 258 | create_blank 259 | copy_iso 260 | start_blank 261 | get_VNC 262 | check_state 263 | snapshot 264 | create_file 265 | create_manifest 266 | show_image_files 267 | clean_up 268 | 269 | exit 0 270 | -------------------------------------------------------------------------------- /create-image-manifest: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (c) 2016 Joyent Inc., All rights reserved. 4 | # 5 | 6 | set -o errexit 7 | 8 | #now=$(date -u +%Y-%m-%dT%H:%MZ) 9 | now=$(date -u +%Y-%m-%dT%TZ) 10 | vm_uuid=$(uuid) 11 | SUM=/usr/bin/sum 12 | 13 | usage() { 14 | cat < -s -v 16 | 17 | -d (optional, default: " KVM Image") 18 | -D (optional, default: "virtio") 19 | -f (required) 20 | -n (required) 21 | -N (optional, default: "virtio") 22 | -o (optional, default: bsd) 23 | -s (required) 24 | -v (required) 25 | -h (optional) 26 | 27 | Example: 28 | 29 | $0 -f freebsd-11-20161019.zfs.gz -n freebsd-11 -s 10240 -v 20161019 -o bsd 30 | 31 | USAGE 32 | exit 1 33 | } 34 | 35 | while getopts d:D:f:n:N:o:s:v:h:? c; do 36 | case ${c} in 37 | d) 38 | description=${OPTARG} 39 | ;; 40 | D) 41 | disk_driver=${OPTARG} 42 | ;; 43 | f) 44 | filename=${OPTARG} 45 | ;; 46 | n) 47 | name=${OPTARG} 48 | ;; 49 | N) 50 | nic_driver=${OPTARG} 51 | ;; 52 | o) 53 | os=${OPTARG} 54 | ;; 55 | s) 56 | image_size=${OPTARG} 57 | ;; 58 | v) 59 | version=${OPTARG} 60 | ;; 61 | h) 62 | homepage=${OPTARG} 63 | ;; 64 | \?) 65 | usage 66 | ;; 67 | esac 68 | done 69 | 70 | if [[ -z ${filename} || -z ${name} || -z ${version} || -z ${image_size} ]]; then 71 | echo "FATAL: All of -f, -n, -s and -v are required." 72 | usage 73 | fi 74 | 75 | if [[ -z ${description} ]]; then 76 | description="${name} ${version} KVM image" 77 | fi 78 | 79 | if [[ -z ${os} ]]; then 80 | os=bsd 81 | fi 82 | 83 | if [[ -z ${homepage} ]]; then 84 | homepage=http://docs.joyent.com/ 85 | fi 86 | 87 | if [[ ! -f ${filename} ]]; then 88 | echo "FATAL: ${filename} does not exist." 89 | usage 90 | fi 91 | 92 | if [[ -z ${disk_driver} ]]; then 93 | disk_driver="virtio" 94 | fi 95 | 96 | if [[ -z ${nic_driver} ]]; then 97 | nic_driver="virtio" 98 | fi 99 | 100 | shasum=$($SUM -x sha1 ${filename} | cut -d' ' -f1) 101 | filesize=$(wc -c < ${filename}) 102 | 103 | cat < -m -p -i -c -d -M -l -f 32 | 33 | Example: 34 | $0 -r 11.0 -m ftp.freebsd.org -p /pub/FreeBSD/releases/ISO-IMAGES -i FreeBSD-11.0-RELEASE-amd64-disc1.iso -c CHECKSUM.SHA256-FreeBSD-11.0-RELEASE-amd64 -d /data/freebsd-iso -M /mnt/freebsd-iso -l /data/freebsd-custom-11.0 -f freebsd-11.0-custom.iso 35 | 36 | OPTIONS: 37 | -r The desired FreeBSD release (e.g., 11.0) 38 | -m The mirror to use when downloading the release ISO. Do not include protocol (e.g., ftp://). Assumes ftp mirror 39 | -p The desired mirror path to the ISO (e.g., /pub/FreeBSD/releases/ISO-IMAGES) 40 | -i The ISO filename 41 | -c The name of the checksum file for the ISO 42 | -d The location to save the dowloaded ISO. Must be absolute path. 43 | -M The mount point for the downloaded ISO 44 | -l The directory location for saving a copy of the ISO layout. Must be absolute path. 45 | -f The name to use for the custom ISO 46 | -h Show this message 47 | 48 | EOF 49 | } 50 | 51 | while getopts "hr:m:p:i:c:d:M:l:f:" OPTION 52 | do 53 | case $OPTION in 54 | h) 55 | usage 56 | exit 1 57 | ;; 58 | r) 59 | RELEASE=${OPTARG} 60 | ;; 61 | m) 62 | MIRROR=${OPTARG%/} 63 | ;; 64 | p) 65 | MIRROR_PATH=${OPTARG%/} 66 | ;; 67 | i) 68 | ISO=${OPTARG} 69 | ;; 70 | c) 71 | ISO_CHECKSUM=${OPTARG} 72 | ;; 73 | d) 74 | ISO_DIR=${OPTARG%/} 75 | ;; 76 | M) 77 | ISO_MOUNT=${OPTARG%/} 78 | ;; 79 | l) 80 | ISO_LAYOUT=${OPTARG%/} 81 | ;; 82 | f) 83 | ISO_FILENAME="./${OPTARG}" 84 | ;; 85 | ?) 86 | usage 87 | exit 88 | ;; 89 | esac 90 | done 91 | 92 | if [[ -z ${RELEASE} ]]; then 93 | echo "Error: missing release value (-r)" 94 | exit 1 95 | fi 96 | 97 | if [[ -z ${MIRROR} ]]; then 98 | echo "Error: missing mirror url (-m)" 99 | exit 1 100 | fi 101 | 102 | if [[ -z ${MIRROR_PATH} ]]; then 103 | echo "Error: missing mirror path (-p)" 104 | exit 1 105 | fi 106 | 107 | if [[ -z ${ISO} ]]; then 108 | echo "Error: missing ISO (-i) value" 109 | exit 1 110 | fi 111 | 112 | if [[ -z ${ISO} ]]; then 113 | echo "Error: missing ISO checksum (-c) value" 114 | exit 1 115 | fi 116 | 117 | if [[ -z ${ISO_DIR} ]]; then 118 | echo "Error: missing ISO directory (-d) value" 119 | exit 1 120 | fi 121 | 122 | if [[ -z ${ISO_MOUNT} ]]; then 123 | echo "Error: missing mount point directory (-M) value" 124 | exit 1 125 | fi 126 | 127 | if [[ -z ${ISO_LAYOUT} ]]; then 128 | echo "Error: missing DVD layout directory (-l) value" 129 | exit 1 130 | fi 131 | 132 | if [[ -z ${ISO_FILENAME} ]]; then 133 | echo "Error: missing custom ISO file name (-f) value" 134 | exit 1 135 | fi 136 | 137 | # Clean up ISO file if download is interupted 138 | trap 'rm -rf $PWD/${ISO_DIR}/${ISO}' SIGHUP SIGINT SIGTERM 139 | # Delete Previous custom layout 140 | trap 'rm -rf $ISO_LAYOUT' SIGHUP SIGINT SIGTERM 141 | 142 | fetch_iso() { 143 | if [[ ! -d $ISO_DIR ]]; then 144 | mkdir -p $ISO_DIR 145 | fi 146 | 147 | echo "==> Fetching ${ISO_CHECKSUM}" 148 | curl -sS -o ${ISO_DIR}/${ISO_CHECKSUM} ftp://${MIRROR}/${MIRROR_PATH}/${RELEASE}/${ISO_CHECKSUM} 149 | 150 | echo "==> Checking for local copy of $ISO..." 151 | if [[ -e $ISO_DIR/$ISO ]]; then 152 | echo "==> Found local copy of $ISO" 153 | else 154 | echo "==> Local copy not found." 155 | echo "==> Fetching ISO from $MIRROR..." 156 | curl -sS -o ${ISO_DIR}/${ISO} ftp://${MIRROR}/${MIRROR_PATH}/${RELEASE}/${ISO} 157 | echo "==> Done!" 158 | echo "==> ${ISO} saved to $ISO_DIR/" 159 | 160 | echo "==> Verifying $ISO with ${ISO_CHECKSUM}" 161 | 162 | if [[ "$(sha256 $ISO_DIR/$ISO | cut -f2 -d= | tr -d '[:space:]')" == "$(grep "($ISO)" $ISO_DIR/${ISO_CHECKSUM} | cut -f2 -d= | tr -d '[:space:]')" ]]; then 163 | echo "==> Checksums match." 164 | else 165 | echo "==> Checksums don't match!" 166 | exit 1 167 | fi 168 | fi 169 | } 170 | 171 | create_layout() { 172 | echo "==> Creating custom ISO Layout" 173 | if [[ -d $ISO_LAYOUT ]]; then 174 | echo "==> Previous layout $ISO_LAYOUT exists...deleting" 175 | rm -rf $ISO_LAYOUT 176 | fi 177 | echo "==> Creating $ISO_LAYOUT" 178 | mkdir -p $ISO_LAYOUT 179 | 180 | if [[ ! -d $ISO_MOUNT ]]; then 181 | echo "==> Creating $ISO_MOUNT ..." 182 | mkdir $ISO_MOUNT 183 | fi 184 | 185 | if df | grep -q $ISO_MOUNT; then 186 | echo "==> Unmounting previous $ISO_MOUNT..." 187 | umount $ISO_MOUNT 188 | fi 189 | 190 | echo "==> Mounting $ISO to $ISO_MOUNT" 191 | mount -t cd9660 /dev/"$(mdconfig -f $ISO_DIR/$ISO)" $ISO_MOUNT 192 | 193 | echo "==> Copying layout from $ISO_MOUNT to $ISO_LAYOUT" 194 | rsync -aq $ISO_MOUNT/ $ISO_LAYOUT 195 | 196 | echo "==> Copying and integrating Triton guesttools:" 197 | # Cleanup previous distribution file 198 | [[ -f $TRITON_DIST_FILE ]] && rm $TRITON_DIST_FILE 199 | 200 | ( cd triton-freebsd-guesttools 201 | tar -cvJpf ../${TRITON_DIST_FILE} ./etc ./lib ./usr 202 | ) 203 | 204 | DISTFILE_SHASUM_STDOUT=$(shasum -a 256 $TRITON_DIST_FILE) 205 | DISTFILE_SHASUM_PLAIN=${DISTFILE_SHASUM_STDOUT% *} 206 | DISTFILE_FILECOUNT=$(tar -tf $TRITON_DIST_FILE | wc -l | tr -d ' ') 207 | 208 | echo -e "${TRITON_DIST_FILE}\t${DISTFILE_SHASUM_PLAIN}\t${DISTFILE_FILECOUNT}\t${TRITON_DIST_FILE%.*}\t\"Triton guesttools\"\ton" >> ${ISO_LAYOUT}/usr/freebsd-dist/MANIFEST 209 | 210 | cp $TRITON_DIST_FILE ${ISO_LAYOUT}/usr/freebsd-dist/${TRITON_DIST_FILE} 211 | 212 | echo "==> Copying $INSTALLER_CFG to $ISO_LAYOUT" 213 | cp $INSTALLER_CFG $ISO_LAYOUT/etc/ 214 | 215 | echo "==> Enable serial and internal consoles" 216 | echo "-Dhv" > $ISO_LAYOUT/boot.config 217 | echo "cuau0 \"/usr/libexec/getty std.38400\" xterm on secure" >> $ISO_LAYOUT/etc/ttys 218 | 219 | echo "==> Setting autoboot delay to 5 seconds" 220 | echo "autoboot_delay=\"5\"" >> $ISO_LAYOUT/boot/loader.conf 221 | 222 | echo "==> Get network up automatically in the blank VM" 223 | echo "ifconfig_vtnet0=\"DHCP\"" >> $ISO_LAYOUT/etc/rc.conf 224 | echo "ifconfig_vtnet1=\"DHCP\"" >> $ISO_LAYOUT/etc/rc.conf 225 | 226 | echo "==> Remove resolv.conf symlink" 227 | rm $ISO_LAYOUT/etc/resolv.conf 228 | 229 | echo "==> Set resolvers in the blank VM" 230 | echo "nameserver 8.8.8.8" >> $ISO_LAYOUT/etc/resolv.conf 231 | echo "nameserver 8.8.4.4" >> $ISO_LAYOUT/etc/resolv.conf 232 | 233 | echo "==> Unmounting $ISO_MOUNT" 234 | umount $ISO_MOUNT 235 | } 236 | 237 | create_newiso() { 238 | echo "==> Getting Volume ID for ${ISO}" 239 | CUSTOM_ISO_TITLE=$(isoinfo -d -i ${ISO_DIR}/${ISO} | grep "Volume id" | awk '{print $3}') 240 | echo "==> Volume ID is $CUSTOM_ISO_TITLE" 241 | 242 | echo "==> Preparing NEW ISO" 243 | mkisofs -J -R -no-emul-boot \ 244 | -V "$CUSTOM_ISO_TITLE" \ 245 | -p "Joyent" -b boot/cdboot \ 246 | -o $ISO_FILENAME $ISO_LAYOUT 247 | echo "==> Custom ISO now ready: $ISO_FILENAME" 248 | } 249 | 250 | echo "==> ISO Build Starting!" 251 | fetch_iso 252 | create_layout 253 | create_newiso 254 | -------------------------------------------------------------------------------- /installerconfig: -------------------------------------------------------------------------------- 1 | PARTITIONS=vtbd0 2 | DISTRIBUTIONS="kernel.txz base.txz triton.txz" 3 | BSDINSTALL_DISTSITE=ftp://ftp.freebsd.org/pub/FreeBSD/releases/amd64/12.0-RELEASE 4 | 5 | #!/bin/sh 6 | 7 | set -o xtrace 8 | echo "==> Running installerconfig" 9 | 10 | # Enable serial and internal consoles 11 | echo "==> Enabling serial and internal consoles" 12 | echo "-Dhv" > /boot.config 13 | echo "cuau0 \"/usr/libexec/getty std.38400\" xterm on secure" >> /etc/ttys 14 | 15 | 16 | echo "==> Adding boot loader settings" 17 | cat << BOOT > /boot/loader.conf 18 | autoboot_delay="5" 19 | verbose_loading="YES" 20 | hw.snd.default_auto=0 21 | hw.usb.disable_enumeration=1 22 | hw.usb.no_boot_wait=1 23 | hw.usb.no_shutdown_wait=1 24 | BOOT 25 | 26 | echo "==> Setting up rc.conf" 27 | cat > /etc/rc.conf << RC_CONF 28 | fsck_y_enable="YES" 29 | 30 | # Enable Triton support. Do not remove. 31 | triton_enable="YES" 32 | 33 | sshd_enable="YES" 34 | ntpd_enable="YES" 35 | ntpd_sync_on_start="YES" 36 | 37 | RC_CONF 38 | 39 | # Set Time Zone to UTC 40 | echo "==> Setting Time Zone to UTC" 41 | /bin/cp /usr/share/zoneinfo/UTC /etc/localtime 42 | /usr/bin/touch /etc/wall_cmos_clock 43 | /sbin/adjkerntz -a 44 | 45 | # Fetch and install binary updates. Ensures we have the latest security fixes. 46 | echo "==> Running freebsd-update fetch and freebsd-update install" 47 | # Remove src from update since it's not installed 48 | # See https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=198030 49 | sed -i.bak -e s/Components\ src\ world\ kernel/Components\ world\ kernel/g /etc/freebsd-update.conf 50 | 51 | cat << FREEBSDUPDATE > /tmp/freebsd-update.conf 52 | KeyPrint 800651ef4b4c71c27e60786d7b487188970f4b4169cc055784e21eb71d410cc5 53 | 54 | ServerName update.FreeBSD.org 55 | 56 | Components world/base kernel 57 | 58 | IgnorePaths 59 | 60 | IDSIgnorePaths /usr/share/man/cat 61 | IDSIgnorePaths /usr/share/man/whatis 62 | IDSIgnorePaths /var/db/locate.database 63 | IDSIgnorePaths /var/log 64 | 65 | UpdateIfUnmodified /etc/ /var/ /root/ /.cshrc /.profile 66 | 67 | MergeChanges /etc/ /boot/device.hints 68 | 69 | BackupKernel no 70 | FREEBSDUPDATE 71 | 72 | env PAGER=cat freebsd-update -f /tmp/freebsd-update.conf fetch 73 | env PAGER=cat freebsd-update -f /tmp/freebsd-update.conf install 74 | 75 | echo "==> Installing packages" 76 | env ASSUME_ALWAYS_YES=YES pkg update -f 77 | env ASSUME_ALWAYS_YES=YES pkg upgrade -q -y 78 | env ASSUME_ALWAYS_YES=YES pkg install -q -y bash curl node npm wget 79 | env ASSUME_ALWAYS_YES=YES pkg autoremove 80 | env ASSUME_ALWAYS_YES=YES pkg clean -a 81 | 82 | echo "==> Enable root login via ssh" 83 | sed -i.bak -e s/#PermitRootLogin\ no/PermitRootLogin\ without-password/g /etc/ssh/sshd_config 84 | 85 | ## Build date used for motd and product file 86 | BUILDDATE=$(date +%Y%m%d) 87 | RELEASE="12.0-RELEASE" 88 | DOC_URL="https://docs.joyent.com/images/kvm/freebsd" 89 | 90 | # Create MOTD 91 | echo "Creating /etc/motd" 92 | mv /etc/motd /etc/motd-backup 93 | cat << MOTD > /etc/motd 94 | __ . . 95 | _| |_ | .-. . . .-. :--. |- 96 | |_ _| ;| || |(.-' | | | 97 | |__| \`--' \`-' \`;-| \`-' ' ' \`-' 98 | / ; Instance (FreeBSD $RELEASE $BUILDDATE) 99 | \`-' $DOC_URL 100 | 101 | MOTD 102 | 103 | # Create product file 104 | echo "Creating /etc/product file" 105 | cat << PRODUCT > /etc/product 106 | Name: Joyent Instance 107 | Image: FreeBSD $RELEASE $BUILDDATE 108 | Documentation: $DOC_URL 109 | Description: FreeBSD $RELEASE 64-bit image with just essential packages \ 110 | installed. Ideal for users who are comfortable with setting up their \ 111 | own environment and tools. 112 | PRODUCT 113 | 114 | echo "Cleaning up" 115 | rm -rf /tmp/installscript 116 | rm -rf /var/db/freebsd-update/* 117 | rm -rf /tmp/freebsd-update.conf 118 | 119 | echo "End of installerconfig" 120 | 121 | # Shutdown/Poweroff 122 | poweroff 123 | -------------------------------------------------------------------------------- /triton-freebsd-guesttools/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 Joyent, Inc., All rights reserved. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE 20 | -------------------------------------------------------------------------------- /triton-freebsd-guesttools/README.md: -------------------------------------------------------------------------------- 1 | # triton-freebsd-guesttools 2 | 3 | This repo provides the FreeBSD kvm guest tools to enabled compatability with SmartOS and Triton. triton-freebsd-guesttools is bundled as a distribution tar and installed as part of the custom ISO build process. See the `create-iso` script for details. 4 | 5 | The mdata-client tools (mdata-get, mdata-list, etc.) are from the [mdata-client](https://github.com/joyent/mdata-client) repo. 6 | -------------------------------------------------------------------------------- /triton-freebsd-guesttools/etc/rc.d/triton: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # REQUIRE: NETWORKING 4 | # PROVIDE: triton 5 | # BEFORE: SERVERS 6 | 7 | . /etc/rc.subr 8 | 9 | name="triton" 10 | 11 | 12 | start_cmd="${name}_start" 13 | stop_cmd=":" 14 | 15 | load_rc_config $name 16 | 17 | triton_start() 18 | { 19 | /lib/smartdc/triton 20 | } 21 | 22 | run_rc_command "$1" 23 | -------------------------------------------------------------------------------- /triton-freebsd-guesttools/lib/smartdc/add-network-interface: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/bash 2 | # 3 | # Copyright (c) 2016 Joyent Inc., All rights reserved. 4 | # This script checks new network interfaces for and enables via DHCP at boot. 5 | 6 | # load common functions and vars 7 | . /lib/smartdc/common.lib 8 | 9 | nic_added=n 10 | 11 | for device in $(ifconfig | grep flags | cut -d: -f1); do 12 | if [[ "lo" == "${device:0:2}" ]]; then 13 | continue 14 | fi 15 | 16 | grep "ifconfig_$device=" /etc/rc.conf &>/dev/null 17 | if [[ $? -ne 0 ]]; then 18 | lib_triton_info "New interface found: $device. Adding to /etc/rc.conf" 19 | echo "ifconfig_$device=\"DHCP\" # Added by triton" >> /etc/rc.conf 20 | 21 | nic_added=y 22 | fi 23 | done 24 | 25 | if [[ "$nic_added" == "y" ]]; then 26 | lib_triton_info "Restarting /etc/rc.d/netif" 27 | /etc/rc.d/netif restart 28 | fi 29 | 30 | exit 0 31 | -------------------------------------------------------------------------------- /triton-freebsd-guesttools/lib/smartdc/common.lib: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/bash 2 | 3 | # 4 | # Copyright (c) 2016 Joyent Inc., All rights reserved. 5 | # 6 | # Common variables used by scripts in /lib/smartdc 7 | 8 | # location of binaries that functions use 9 | LOGGER=/usr/bin/logger 10 | MDATA_GET='/usr/sbin/mdata-get' 11 | 12 | set -o xtrace 13 | 14 | # Common functions used by scripts /lib/smartdc 15 | 16 | lib_triton_fatal() { 17 | echo "(fatal) - $0 - $@" 18 | $LOGGER "(fatal) - $0 - $@" 19 | exit 1 20 | } 21 | 22 | lib_triton_info() { 23 | echo "(info) - $0 - $@" 24 | $LOGGER "(info) - $0 - $@" 25 | } 26 | 27 | export -f lib_triton_fatal 28 | export -f lib_triton_info 29 | -------------------------------------------------------------------------------- /triton-freebsd-guesttools/lib/smartdc/firstboot: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/bash 2 | 3 | # Copyright (c) 2016 Joyent Inc., All rights reserved. 4 | # For scripts that should be run on first boot only 5 | 6 | # load common functions and vars 7 | . /lib/smartdc/common.lib 8 | 9 | # Set root password if root_pw is set in the image manifest 10 | (/lib/smartdc/set-rootpassword) 11 | 12 | # Format disk 13 | (/lib/smartdc/format-secondary-disk) 14 | 15 | # Disable firstboot once all scripts are run 16 | lib_triton_info "Disabling firstboot" 17 | touch /lib/smartdc/.firstboot-complete-do-not-delete 18 | 19 | exit 0 20 | -------------------------------------------------------------------------------- /triton-freebsd-guesttools/lib/smartdc/format-secondary-disk: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/bash 2 | 3 | # 4 | # Copyright (c) 2016 Joyent Inc., All rights reserved. 5 | # 6 | # formats the FreeeBSD secondary disk ( /dev/vtbd1p1 ) 7 | # also refered to as the /data disk 8 | 9 | # Users can provision this disk how they like 10 | # By default we provision the whole disk as one partition 11 | 12 | # load common functions and vars 13 | . /lib/smartdc/common.lib 14 | 15 | DATADISKDEVICE='vtbd1' 16 | GPART=/sbin/gpart 17 | 18 | checkformount() { 19 | fstest=$(df -h | grep "/dev/${DATADISKDEVICE}p1") 20 | if [[ -n "$fstest" ]] ; then 21 | fssize=$(echo $fstest | sed -E '/[[:space:]]{2,}/s// /g' | cut -d ' ' -f2) 22 | lib_triton_info "$fssize data disk is mounted on /dev/${DATADISKDEVICE}p1" 23 | return 1 24 | else 25 | lib_triton_info "no data disk is mounted on /dev/${DATADISKDEVICE}p1" 26 | return 0 27 | fi 28 | } 29 | 30 | # Start of Main 31 | 32 | # check for device 33 | if [[ ! -e /dev/${DATADISKDEVICE} ]] ; then 34 | lib_triton_fatal "secondary disk '/dev/${DATADISKDEVICE}' not found. exiting." 35 | fi 36 | 37 | if [[ -z $GPART ]] ; then 38 | lib_triton_fatal "gpart binary not found. exiting." 39 | fi 40 | 41 | ## Sanity check 42 | checkformount 43 | return_val=$? 44 | if [[ "$return_val" -eq 1 ]]; then 45 | lib_triton_fatal "data disk is already mounted" 46 | else 47 | lib_triton_info "no data disk is mounted" 48 | fi 49 | 50 | ## make sure that a partiton does not already exist 51 | ## we do not want to delete any data 52 | partexists=$($GPART show /dev/${DATADISKDEVICE} | grep "1 freebsd-ufs" | wc -l | tr -d ' ') 53 | if [[ $partexists -ne 0 ]] ; then 54 | lib_triton_fatal "Data disk partition '/dev/${DATADISKDEVICE}p1' found. Exiting to prevent deleting data. You will have to format data disk partition manually." 55 | exit 0; 56 | fi 57 | 58 | ## create the data disk 59 | 60 | # making partition table 61 | lib_triton_info "creating gpt partition type /dev/${DATADISKDEVICE}" 62 | gpart create -s gpt $DATADISKDEVICE 63 | 64 | DISKSIZE=$(gpart show /dev/${DATADISKDEVICE} | grep free | cut -d'-' -f3 | cut -d'(' -f2 | cut -d')' -f1) 65 | 66 | lib_triton_info "disksize is $DISKSIZE on $DATADISKDEVICE" 67 | 68 | lib_triton_info "creating partition /dev/${DATADISKDEVICE}" 69 | 70 | # need this sleep to let partition table to update 71 | # if not then /dev/vdb1 will not exist 72 | lib_triton_info "sleeping for update of partition table for /dev/${DATADISKDEVICE}" 73 | sleep 2 74 | 75 | # creating a single partition for the whole disk, formatting it, and mounting it 76 | gpart add -t freebsd-ufs ${DATADISKDEVICE} 77 | 78 | if [[ -e /dev/${DATADISKDEVICE}p1 ]] ; then 79 | lib_triton_info "creating new filesystem on /dev/${DATADISKDEVICE}p1" 80 | newfs -L DATA /dev/${DATADISKDEVICE}p1 81 | else 82 | lib_triton_fatal "did not create filesystem on /dev/${DATADISKDEVICE}p1" 83 | fi 84 | 85 | # Check for /data and make it 86 | if [[ ! -e /data ]]; then 87 | lib_triton_info "making /data dir mount point" 88 | mkdir /data 89 | fi 90 | 91 | # add entry to fstab so data disk is mounted on reboot 92 | fsentry=$(grep "/dev/${DATADISKDEVICE}p1" /etc/fstab | wc -l | tr -d ' ') 93 | echo "-- $fsentry --" 94 | if [[ $fsentry -eq 0 ]] ; then 95 | lib_triton_info "adding fstab entry for /dev/${DATADISKDEVICE}p1" 96 | printf "/dev/${DATADISKDEVICE}p1\t/data\t\tufs\trw\t2\t2\n" >> /etc/fstab 97 | else 98 | lib_triton_info "not adding as fstab entry already exist for /dev/${DATADISKDEVICE}p1" 99 | fi 100 | 101 | # fsck disk 102 | lib_triton_info "fscking /dev/${DATADISKDEVICE}p1" 103 | fsck -y -t ufs /dev/${DATADISKDEVICE}p1 104 | 105 | # enable journeling 106 | lib_triton_info "enabling journeling /dev/${DATADISKDEVICE}p1" 107 | tunefs -j enable /dev/${DATADISKDEVICE}p1 108 | 109 | # mount the data disk 110 | lib_triton_info "mounting /dev/${DATADISKDEVICE}p1 as /data" 111 | mount /data 112 | 113 | checkformount 114 | return_val=$? 115 | if [[ "$return_val" -eq 1 ]]; then 116 | lib_triton_info "data disk is mounted" 117 | else 118 | lib_triton_fatal "no data disk is mounted" 119 | fi 120 | 121 | exit 0 122 | -------------------------------------------------------------------------------- /triton-freebsd-guesttools/lib/smartdc/get-user-data: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/bash 2 | # 3 | # Copyright (c) 2016 Joyent Inc., All rights reserved. 4 | # 5 | # Get metadata user-data (via mdata-get) 6 | # This script is executed every boot and must be executed 7 | # before script "run-user-script" 8 | 9 | # load common functions and vars 10 | . /lib/smartdc/common.lib 11 | 12 | lib_triton_info "Retrieving metadata user-data" 13 | $MDATA_GET user-data >/var/tmp/mdata-user-data.new 14 | case $? in 15 | 0) 16 | lib_triton_info "Metadata user-data successfuly retrieved." 17 | mv /var/tmp/mdata-user-data{.new,} 18 | lib_triton_info "User-data saved to /var/tmp/mdata-user-data." 19 | ;; 20 | 1) 21 | lib_triton_info "Metadata user-data not defined." 22 | rm -f /var/tmp/mdata-user-data{,.new} 23 | ;; 24 | *) 25 | lib_triton_info "Metadata couldn't be retrieved." 26 | exit 1 27 | ;; 28 | esac 29 | 30 | exit 0 31 | -------------------------------------------------------------------------------- /triton-freebsd-guesttools/lib/smartdc/run-operator-script: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/bash 2 | # 3 | # Copyright (c) 2016 Joyent Inc., All rights reserved. 4 | # 5 | 6 | . /lib/smartdc/common.lib 7 | 8 | lib_triton_info "Retrieving metadata operator-script..." 9 | $MDATA_GET sdc:operator-script >/var/tmp/mdata-operator-script.new 10 | case $? in 11 | 0) 12 | lib_triton_info "Metadata operator-script successfuly retrieved." 13 | mv /var/tmp/mdata-operator-script{.new,} 14 | chmod +x /var/tmp/mdata-operator-script 15 | ;; 16 | 1) 17 | lib_triton_info "Metadata operator-script not defined." 18 | rm -f /var/tmp/mdata-operator-script{,.new} 19 | ;; 20 | *) 21 | lib_triton_fatal "Metadata couldn't be retrieved." 22 | ;; 23 | esac 24 | 25 | if [[ -x /var/tmp/mdata-operator-script ]]; then 26 | lib_triton_info "Executing metadata operator-script" 27 | /var/tmp/mdata-operator-script 28 | operator_script_exit=$? 29 | if [[ ${operator_script_exit} -gt 0 ]]; then 30 | lib_triton_info "WARNING: operator-script failed: exited \ 31 | ${operator_script_exit}" >&2 32 | fi 33 | fi 34 | -------------------------------------------------------------------------------- /triton-freebsd-guesttools/lib/smartdc/run-user-script: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/bash 2 | # 3 | # Copyright (c) 2016 Joyent Inc., All rights reserved. 4 | # 5 | # Script that will use mdata field of run_userscript_flag 6 | # If field is set to TRUE, when this script is ran, then the mdata user-script 7 | # is updated and executed 8 | # By default the mdata user-script is only ran once on the first boot after 9 | # provisioning 10 | # This script is executed on each system boot 11 | 12 | # load common functions and vars 13 | . /lib/smartdc/common.lib 14 | 15 | lib_triton_info "Retrieving metadata user-script..." 16 | $MDATA_GET user-script >/var/tmp/mdata-user-script.new 17 | case $? in 18 | 0) 19 | lib_triton_info "Metadata user-script successfuly retrieved." 20 | mv /var/tmp/mdata-user-script{.new,} 21 | chmod +x /var/tmp/mdata-user-script 22 | ;; 23 | 1) 24 | lib_triton_info "Metadata user-script not defined." 25 | rm -f /var/tmp/mdata-user-script{,.new} 26 | ;; 27 | *) 28 | lib_triton_fatal "Metadata couldn't be retrieved." 29 | ;; 30 | esac 31 | 32 | user_script_exit=0 33 | if [[ -x /var/tmp/mdata-user-script ]]; then 34 | lib_triton_info "Executing metadata user-script" 35 | USER_SCRIPT_LOG=/var/log/mdata-user-script.log 36 | if [[ ! -e $USER_SCRIPT_LOG ]]; then 37 | touch $USER_SCRIPT_LOG 38 | fi 39 | /var/tmp/mdata-user-script >> $USER_SCRIPT_LOG 2>&1 40 | [[ $? -gt 0 ]] && user_script_exit=95 41 | fi 42 | 43 | exit ${user_script_exit} 44 | -------------------------------------------------------------------------------- /triton-freebsd-guesttools/lib/smartdc/set-hostname: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/bash 2 | # 3 | # Copyright (c) 2016 Joyent Inc., All rights reserved. 4 | # Set the hostname of the VM if it's not already configured by the user. 5 | 6 | # load common functions and vars 7 | . /lib/smartdc/common.lib 8 | 9 | grep hostname= /etc/rc.conf &>/dev/null 10 | if [[ $? -ne 0 ]]; then 11 | lib_triton_info "No hostname set in /etc/rc.conf." 12 | hostname=$($MDATA_GET sdc:hostname) && \ 13 | lib_triton_info "Setting hostname to sdc:hostname: $hostname." 14 | 15 | if [[ $? -ne 0 ]]; then 16 | lib_triton_info "No value set for sdc:hostname." 17 | hostname=$($MDATA_GET sdc:uuid) && \ 18 | lib_triton_info "Setting hostname to sdc:uuid: $hostname" 19 | 20 | if [[ $? -ne 0 ]]; then 21 | lib_triton_info "No value set for sdc:uuid. Setting empty hostname." 22 | hostname="" 23 | 24 | fi 25 | fi 26 | 27 | if [[ ! -z "$hostname" ]]; then 28 | lib_triton_info "Restarting /etc/rc.d/hostname" 29 | echo hostname="\"$hostname\" # Added by triton. This can be modified." >> /etc/rc.conf 30 | /etc/rc.d/hostname restart 31 | fi 32 | fi 33 | 34 | exit 0 35 | -------------------------------------------------------------------------------- /triton-freebsd-guesttools/lib/smartdc/set-root-authorized-keys: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/bash 2 | # 3 | # Copyright (c) 2016 Joyent Inc., All rights reserved. 4 | # 5 | # Script that will overwrite ~/.ssh/authorized keys if mdata field overwrite_root_akeys = OVERWRITE 6 | # This allows for customers to update ssh keys when running this script 7 | # By default this script is called on each boot 8 | 9 | # load common functions and vars 10 | . /lib/smartdc/common.lib 11 | 12 | if [[ ! -f /root/.ssh/authorized_keys ]]; then 13 | authorized_keys=$($MDATA_GET root_authorized_keys | awk '{ sub(/(ssh-rsa )/,"\n&"); print }' | awk '{ sub(/(ssh-dss )/,"\n&"); print }' 2>>/dev/console) 14 | if [[ -n ${authorized_keys} ]]; then 15 | mkdir -p /root/.ssh 16 | echo -e "${authorized_keys}" > /root/.ssh/authorized_keys 17 | lib_triton_info "Creating /root/.ssh/authorized_keys with Metadata field root_authorized_keys" 18 | chmod 700 /root/.ssh 19 | chmod 600 /root/.ssh/authorized_keys 20 | fi 21 | fi 22 | 23 | exit 0 24 | -------------------------------------------------------------------------------- /triton-freebsd-guesttools/lib/smartdc/set-rootpassword: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/bash 2 | # 3 | # Copyright (c) 2016 Joyent Inc., All rights reserved. 4 | # 5 | # This script sets the password for the root user if this: 6 | # 7 | # "users": [{"name": "root"}] 8 | # 9 | # has been set in the image manifest. 10 | # 11 | # This script must only be run once via firstboot. The script will first check 12 | # /etc/master.passwd to ensure a root password is not being overwritten. 13 | 14 | # load common functions and vars 15 | . /lib/smartdc/common.lib 16 | 17 | # Check /etc/master.passwd. If root pass is set, exit so we don't clobber an 18 | # already set password. 19 | passset=$(cat /etc/master.passwd | grep Charlie | awk -F':' '{print $2;}') 20 | if [[ -n $passset ]]; then 21 | lib_triton_fatal "The root password already set in /etc/master.passwd. Exiting." 22 | fi 23 | 24 | # Check if root_pw is set in meta data 25 | pass=$($MDATA_GET root_pw) 26 | if [[ $? -eq 0 ]] ; then 27 | lib_triton_info "Setting root password to value of meta-data root_pw." 28 | echo "${pass}" | pw usermod root -h 0 29 | else 30 | lib_triton_info "No root password set in root_pw. Skipping." 31 | fi 32 | 33 | exit 0 34 | -------------------------------------------------------------------------------- /triton-freebsd-guesttools/lib/smartdc/triton: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/bash 2 | # 3 | # Copyright (c) 2016 Joyent Inc., All rights reserved. 4 | 5 | # Log output 6 | LOG='/var/log/triton.log' 7 | if [[ ! -e $LOG ]] ; then 8 | touch $LOG 9 | fi 10 | 11 | exec 4<> $LOG 12 | export PS4='[\D{%FT%TZ}] ${BASH_SOURCE}:${LINENO}: ${FUNCNAME[0]:+${FUNCNAME[0]}(): }' 13 | export BASH_XTRACEFD=4 14 | set -o xtrace 15 | 16 | (/lib/smartdc/add-network-interface) 17 | (/lib/smartdc/set-hostname) 18 | (/lib/smartdc/set-root-authorized-keys) 19 | if [ ! -f /lib/smartdc/.firstboot-complete-do-not-delete ] ; then 20 | (/lib/smartdc/firstboot) 21 | fi 22 | (/lib/smartdc/run-operator-script) 23 | (/lib/smartdc/get-user-data) 24 | (/lib/smartdc/run-user-script) 25 | -------------------------------------------------------------------------------- /triton-freebsd-guesttools/usr/sbin/mdata-delete: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TritonDataCenter/freebsd-kvm-image-builder/cbfe58cf6e87ae18ea67ab83388ceb5aa2b4ab6e/triton-freebsd-guesttools/usr/sbin/mdata-delete -------------------------------------------------------------------------------- /triton-freebsd-guesttools/usr/sbin/mdata-get: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TritonDataCenter/freebsd-kvm-image-builder/cbfe58cf6e87ae18ea67ab83388ceb5aa2b4ab6e/triton-freebsd-guesttools/usr/sbin/mdata-get -------------------------------------------------------------------------------- /triton-freebsd-guesttools/usr/sbin/mdata-list: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TritonDataCenter/freebsd-kvm-image-builder/cbfe58cf6e87ae18ea67ab83388ceb5aa2b4ab6e/triton-freebsd-guesttools/usr/sbin/mdata-list -------------------------------------------------------------------------------- /triton-freebsd-guesttools/usr/sbin/mdata-put: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TritonDataCenter/freebsd-kvm-image-builder/cbfe58cf6e87ae18ea67ab83388ceb5aa2b4ab6e/triton-freebsd-guesttools/usr/sbin/mdata-put -------------------------------------------------------------------------------- /triton-freebsd-guesttools/usr/share/man/man1/mdata-delete.1: -------------------------------------------------------------------------------- 1 | .\" Copyright (c) 2013, Joyent, Inc. 2 | .\" See LICENSE file for copyright and license details. 3 | 4 | .TH "MDATA-DELETE" "1" "October 2013" "Joyent SmartDataCenter" "Metadata Commands" 5 | 6 | .SH "NAME" 7 | \fBmdata-delete\fR \-\- Delete a metadata key-value pair\. 8 | 9 | .SH "SYNOPSIS" 10 | . 11 | .nf 12 | \fB/usr/sbin/mdata-delete\fR \fIkeyname\fR 13 | .fi 14 | 15 | .SH "DESCRIPTION" 16 | .sp 17 | .LP 18 | The \fBmdata-delete\fR command allows the user (or a script) to modify the 19 | metadata for a guest instance running in a \fISmartDataCenter (SDC)\fR cloud. 20 | Metadata values are generally set programmatically via \fICloudAPI\fR, or 21 | during interactive provisioning via a Web Portal. They may also be set from 22 | within the instance with the \fBmdata-put\fR command. 23 | .sp 24 | .LP 25 | The key-value pair for \fIkeyname\fR will be removed permanently from the 26 | metadata stored for this guest instance. Deletion of a key which did not 27 | exist is not considered an error. 28 | .sp 29 | .LP 30 | If the metadata service is unavailable at the time of the request, this command 31 | will block waiting for it to become available. Non-transient failures will 32 | cause the program to exit with a non-zero status. Depending on the nature of 33 | the error, some diagnostic output may be printed to \fBstderr\fR. 34 | 35 | .SH "EXIT STATUS" 36 | .sp 37 | .LP 38 | The following exit values are returned: 39 | 40 | .sp 41 | .ne 2 42 | .na 43 | \fB0\fR 44 | .ad 45 | .RS 5n 46 | Successful completion. 47 | .sp 48 | The key-value pair named \fIkeyname\fR was removed from the instance metadata, 49 | or did not initially exist. 50 | .RE 51 | 52 | .sp 53 | .ne 2 54 | .na 55 | \fB2\fR 56 | .ad 57 | .RS 5n 58 | An error occurred. 59 | .sp 60 | An unexpected error condition occurred, which is believed to be a 61 | non-transient condition. Retrying the request is not expected to 62 | resolve the error condition; either a software bug or misconfiguration 63 | exists. 64 | .RE 65 | 66 | .sp 67 | .ne 2 68 | .na 69 | \fB3\fR 70 | .ad 71 | .RS 5n 72 | A usage error occurred. 73 | .sp 74 | Malformed arguments were passed to the program. Check the usage instructions 75 | to ensure valid arguments are supplied. 76 | .RE 77 | 78 | .SH "SEE ALSO" 79 | .sp 80 | .LP 81 | \fBmdata-get\fR(1), \fBmdata-list\fR(1), \fBmdata-put\fR(1) 82 | -------------------------------------------------------------------------------- /triton-freebsd-guesttools/usr/share/man/man1/mdata-get.1: -------------------------------------------------------------------------------- 1 | .\" Copyright (c) 2013, Joyent, Inc. 2 | .\" See LICENSE file for copyright and license details. 3 | 4 | .TH "MDATA-GET" "1" "October 2013" "Joyent SmartDataCenter" "Metadata Commands" 5 | 6 | .SH "NAME" 7 | \fBmdata-get\fR \-\- Fetch the value of a metadata key-value pair\. 8 | 9 | .SH "SYNOPSIS" 10 | . 11 | .nf 12 | \fB/usr/sbin/mdata-get\fR \fIkeyname\fR 13 | .fi 14 | 15 | .SH "DESCRIPTION" 16 | .sp 17 | .LP 18 | The \fBmdata-get\fR command allows the user (or a script) to query the metadata 19 | for a guest instance running in a \fISmartDataCenter (SDC)\fR cloud. Metadata 20 | values are generally set programmatically via \fICloudAPI\fR, or during 21 | interactive provisioning via a Web Portal. They may also be set from within 22 | the instance with the \fBmdata-put\fR command. 23 | .sp 24 | .LP 25 | The value of the requested \fIkeyname\fR will be printed to \fBstdout\fR. If 26 | the metadata service is unavailable at the time of the request, this command 27 | will block waiting for it to become available. Non-transient failures, such 28 | as the non-existence of the requested \fIkeyname\fR, will cause the program 29 | to exit with a non-zero status. Depending on the nature of the error, some 30 | diagnostic output may be printed to \fBstderr\fR. 31 | 32 | .SH "EXIT STATUS" 33 | .sp 34 | .LP 35 | The following exit values are returned: 36 | 37 | .sp 38 | .ne 2 39 | .na 40 | \fB0\fR 41 | .ad 42 | .RS 5n 43 | Successful completion. 44 | .sp 45 | The requested \fIkeyname\fR was available, and its value was emitted to 46 | \fBstdout\fR. 47 | .RE 48 | 49 | .sp 50 | .ne 2 51 | .na 52 | \fB1\fR 53 | .ad 54 | .RS 5n 55 | Metadata value not found. 56 | .sp 57 | The requested \fIkeyname\fR was not found in the metadata. 58 | .RE 59 | 60 | .sp 61 | .ne 2 62 | .na 63 | \fB2\fR 64 | .ad 65 | .RS 5n 66 | An error occurred. 67 | .sp 68 | An unexpected error condition occurred, which is believed to be a 69 | non-transient condition. Retrying the request is not expected to 70 | resolve the error condition; either a software bug or misconfiguration 71 | exists. 72 | .RE 73 | 74 | .sp 75 | .ne 2 76 | .na 77 | \fB3\fR 78 | .ad 79 | .RS 5n 80 | A usage error occurred. 81 | .sp 82 | Malformed arguments were passed to the program. Check the usage instructions 83 | to ensure valid arguments are supplied. 84 | .RE 85 | 86 | .SH "SEE ALSO" 87 | .sp 88 | .LP 89 | \fBmdata-delete\fR(1), \fBmdata-list\fR(1), 90 | \fBmdata-put\fR(1) 91 | -------------------------------------------------------------------------------- /triton-freebsd-guesttools/usr/share/man/man1/mdata-list.1: -------------------------------------------------------------------------------- 1 | .\" Copyright (c) 2013, Joyent, Inc. 2 | .\" See LICENSE file for copyright and license details. 3 | 4 | .TH "MDATA-LIST" "1" "October 2013" "Joyent SmartDataCenter" "Metadata Commands" 5 | 6 | .SH "NAME" 7 | \fBmdata-list\fR \-\- Fetch the list of available metadata key-value pairs\. 8 | 9 | .SH "SYNOPSIS" 10 | . 11 | .nf 12 | \fB/usr/sbin/mdata-list\fR 13 | .fi 14 | 15 | .SH "DESCRIPTION" 16 | .sp 17 | .LP 18 | The \fBmdata-list\fR command allows the user (or a script) to query the metadata 19 | for a guest instance running in a \fISmartDataCenter (SDC)\fR cloud. Metadata 20 | values are generally set programmatically via \fICloudAPI\fR, or during 21 | interactive provisioning via a Web Portal. They may also be set from within 22 | the instance with the \fBmdata-put\fR command. The value of a key-value pair 23 | may be obtained by passing its name to the \fBmdata-get\fR command. 24 | .sp 25 | .LP 26 | The list of all customer-provided metadata key-value pairs will be printed to 27 | \fBstdout\fR. If the metadata service is unavailable at the time of the 28 | request, this command will block waiting for it to become available. 29 | Non-transient failures will cause the program to exit with a non-zero status. 30 | Depending on the nature of the error, some diagnostic output may be printed to 31 | \fBstderr\fR. 32 | 33 | .SH "EXIT STATUS" 34 | .sp 35 | .LP 36 | The following exit values are returned: 37 | 38 | .sp 39 | .ne 2 40 | .na 41 | \fB0\fR 42 | .ad 43 | .RS 5n 44 | Successful completion. 45 | .sp 46 | The list of key-value pairs was emitted to \fBstdout\fR. 47 | .RE 48 | 49 | .sp 50 | .ne 2 51 | .na 52 | \fB2\fR 53 | .ad 54 | .RS 5n 55 | An error occurred. 56 | .sp 57 | An unexpected error condition occurred, which is believed to be a 58 | non-transient condition. Retrying the request is not expected to 59 | resolve the error condition; either a software bug or misconfiguration 60 | exists. 61 | .RE 62 | 63 | .sp 64 | .ne 2 65 | .na 66 | \fB3\fR 67 | .ad 68 | .RS 5n 69 | A usage error occurred. 70 | .sp 71 | Malformed arguments were passed to the program. Check the usage instructions 72 | to ensure valid arguments are supplied. 73 | .RE 74 | 75 | .SH "SEE ALSO" 76 | .sp 77 | .LP 78 | \fBmdata-delete\fR(1), \fBmdata-get\fR(1), 79 | \fBmdata-put\fR(1) 80 | -------------------------------------------------------------------------------- /triton-freebsd-guesttools/usr/share/man/man1/mdata-put.1: -------------------------------------------------------------------------------- 1 | .\" Copyright (c) 2013, Joyent, Inc. 2 | .\" See LICENSE file for copyright and license details. 3 | 4 | .TH "MDATA-PUT" "1" "October 2013" "Joyent SmartDataCenter" "Metadata Commands" 5 | 6 | .SH "NAME" 7 | \fBmdata-put\fR \-\- Set the value of a metadata key-value pair\. 8 | 9 | .SH "SYNOPSIS" 10 | . 11 | .nf 12 | \fB/usr/sbin/mdata-put\fR \fIkeyname\fR [ \fIvalue\fR ] 13 | .fi 14 | 15 | .SH "DESCRIPTION" 16 | .sp 17 | .LP 18 | The \fBmdata-put\fR command allows the user (or a script) to modify the metadata 19 | for a guest instance running in a \fISmartDataCenter (SDC)\fR cloud. Metadata 20 | values are generally set programmatically via \fICloudAPI\fR, or during 21 | interactive provisioning via a Web Portal. The value of a key-value pair 22 | may be obtained by passing its name to the \fBmdata-get\fR command. 23 | .sp 24 | .LP 25 | The key-value pair named \fIkeyname\fR will be updated in the metadata store 26 | for this instance. If a \fIvalue\fR argument is provided on the command-line, 27 | then that value will be used. Otherwise, if \fIstdin\fR is not a tty, the 28 | value will be read from \fIstdin\fR. 29 | .sp 30 | .LP 31 | If the metadata service is unavailable at the time of the request, this command 32 | will block waiting for it to become available. Non-transient failures, such as 33 | the non-existence of the requested \fIkeyname\fR, will cause the program to 34 | exit with a non-zero status. Depending on the nature of the error, some 35 | diagnostic output may be printed to \fBstderr\fR. 36 | 37 | .SH "EXIT STATUS" 38 | .sp 39 | .LP 40 | The following exit values are returned: 41 | 42 | .sp 43 | .ne 2 44 | .na 45 | \fB0\fR 46 | .ad 47 | .RS 5n 48 | Successful completion. 49 | .sp 50 | The requested \fIkeyname\fR was valid, and its value was updated. 51 | .RE 52 | 53 | .sp 54 | .ne 2 55 | .na 56 | \fB2\fR 57 | .ad 58 | .RS 5n 59 | An error occurred. 60 | .sp 61 | An unexpected error condition occurred, which is believed to be a 62 | non-transient condition. Retrying the request is not expected to 63 | resolve the error condition; either a software bug or misconfiguration 64 | exists. 65 | .RE 66 | 67 | .sp 68 | .ne 2 69 | .na 70 | \fB3\fR 71 | .ad 72 | .RS 5n 73 | A usage error occurred. 74 | .sp 75 | Malformed arguments were passed to the program. Check the usage instructions 76 | to ensure valid arguments are supplied. 77 | .RE 78 | 79 | .SH "SEE ALSO" 80 | .sp 81 | .LP 82 | \fBmdata-delete\fR(1), \fBmdata-get\fR(1), 83 | \fBmdata-list\fR(1) 84 | --------------------------------------------------------------------------------