&1", $sys_msg, $sys_err_no); if ($sys_err_no) { // not mounted // try to mount the cd $mount_err = exec("mount_cd9660 /dev/$cdDevice $cloudInitMountPoint", $sys_msg, $sys_err_no); if (!$sys_err_no) { if (checkCloudInitFiles( $cloudInitFiles, $cloudInitMountPoint)) { syslog(LOG_INFO,"cloud-init: found cloud init drive on $cdDevice mounted at $cloudInitMountPoint/"); return true; } else { $umount_err = exec("umount $cloudInitMountPoint", $sys_msg, $sys_err_no); if ($sys_err_no) { syslog(LOG_ERR,"cloud-init: mounted a wrong device $cdDevice but not able to umount because $sys_msg"); return false; } } } } else { //already mounted (but not by us) if (checkCloudInitFiles( $cloudInitFiles, $cloudInitMountPoint)) { syslog(LOG_INFO,"cloud-init: found cloud init drive on $cdDevice at $cloudInitMountPoint/"); return true; } else { syslog(LOG_ERR,"cloud-init: expected files on cloud init drive not found"); return false; } } } return false; } /** * does a case insensitive search for a network device by given hardware address * * @param string $mac hardware address * @return string $if[1] device name or false if no device could be found */ function searchIfDevice( $mac) { exec("ifconfig -a | awk '/^[a-z]/ { gsub(/\:/,\"\", $1); iface=$1; next } /hwaddr/ { mac=$2; print mac, iface}'", $ifMacList, $sys_err_no); foreach($ifMacList as $ifMac) { $if = explode(" ",$ifMac); if (strcasecmp("$if[0]", "$mac") == 0) { // case insensitive return $if[1]; } } return false; } // search and mount the cloud-init image or exit 1 if (!checkCloudInitDevice( $cloudInitFiles, $cloudInitMountPoint)) { syslog(LOG_ERR,"cloud-init: no cloud init drive available, skipping...\n"); exit(1); } // update the local copy of cloud-init files if there are any changes or exit 0 if (!(updateCloudInitFiles( $cloudInitFiles, $cloudInitLocalPath, $cloudInitMountPoint))) { syslog(LOG_INFO,"cloud-init: cloud init files up to date, skipping...\n"); exit(0); } // parse cloud init configurations // $metaData = Spyc::YAMLLoad("$cloudInitLocalPath/$cloudInitFiles[0]"); // meta-data (actually not in use) $netData = Spyc::YAMLLoad("$cloudInitLocalPath/$cloudInitFiles[1]"); // network-config $userData = Spyc::YAMLLoad("$cloudInitLocalPath/$cloudInitFiles[2]"); // user-data // configure nameserver if set $ifLastNr=(count($netData['config'])-1); // the YAML parser reurns a crappy array like this if (reset($netData['config'][$ifLastNr]) == 'nameserver') { // ( next($netData['config'][$ifLastNr]); // [type] => nameserver $dnsServerCount = 0; // [address] => while($nameserverIP=next($netData['config'][$ifLastNr])) { // [0] => 1.2.3.4 $config['system']['dnsserver'][$dnsServerCount] = $nameserverIP; // [1] => 4.3.2.1 $dnsServerCount++; // [search] => } // [2] => mydomain.local $config['system']['domain'] = next($netData['config'][$ifLastNr]); // ) } // configure WAN interface $wanDevice = searchIfDevice( $netData['config'][0]['mac_address']); if (!$wanDevice) { syslog(LOG_ERR,"cloud-init: no WAN device found"); exit(1); } else { $config['interfaces']['wan']['if'] = $wanDevice; } if ($netData['config'][0][0]['type'] == 'static') { $config['interfaces']['wan']['ipaddr'] = $netData['config'][0][0]['address']; $config['interfaces']['wan']['subnet'] = 32 - log((ip2long($netData['config'][0][0]['netmask']) ^ ip2long('255.255.255.255')) + 1 ,2); $config['interfaces']['wan']['gateway'] = $netData['config'][0][0]['gateway']; } // configure primary LAN device $lanDevice = searchIfDevice( $netData['config'][1]['mac_address']); if (!$lanDevice) { syslog(LOG_ERR,"cloud-init: no LAN device found"); exit(1); } else { $config['interfaces']['lan']['if'] = $lanDevice; } if ($netData['config'][1][0]['type'] == 'static') { $config['interfaces']['lan']['ipaddr'] = $netData['config'][1][0]['address']; $config['interfaces']['lan']['subnet'] = 32 - log((ip2long($netData['config'][1][0]['netmask']) ^ ip2long('255.255.255.255')) + 1 ,2); $config['interfaces']['lan']['gateway'] = $netData['config'][1][0]['gateway']; } // configure additional network devices if ($ifLastNr > 2) { for ($ifNr=2;$ifNr<$ifLastNr;$ifNr++) { $optDeviceName = "opt" . strval($ifNr-1); $optDevice = searchIfDevice( $netData['config'][$ifNr]['mac_address']); if (!$optDevice) { syslog(LOG_WARN,"cloud-init: given network device {$netData['config'][$ifNr]['mac_address']} not found"); break; } else { $config['interfaces'][$optDeviceName]['if'] = $optDevice; } if ($netData['config'][$ifNr][0]['type'] == 'static') { $config['interfaces'][$optDeviceName]['ipaddr'] = $netData['config'][$ifNr][0]['address']; $config['interfaces'][$optDeviceName]['subnet'] = 32 - log((ip2long($netData['config'][$ifNr][0]['netmask']) ^ ip2long('255.255.255.255')) + 1 ,2); $config['interfaces'][$optDeviceName]['gateway'] = $netData['config'][$ifNr][0]['gateway']; } } } // add ssh keys if (isset($userData['ssh_authorized_keys'])) { foreach ($userData[ssh_authorized_keys] as $sshKey) { $sshKeys .= "$sshKey\n"; } $config['system']['user'][0]['authorizedkeys'] = base64_encode("$sshKeys"); } $config['system']['hostname'] = $userData['hostname']; $config['system']['user'][0]['bcrypt-hash'] = $userData['password']; // write the configuration write_config(); // finally reboot the system system_reboot_sync();