Skip to content

Commit cc0ed77

Browse files
author
Chiradeep Vittal
committed
bug 8199: always update the keypairs on disk to account for multiple management servers
1 parent fd081dc commit cc0ed77

3 files changed

Lines changed: 135 additions & 25 deletions

File tree

scripts/vm/systemvm/injectkeys.sh

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
#set -x
77

8-
TMP=/tmp
8+
TMP=${HOME}/tmp
99
SYSTEMVM_PATCH_DIR=../../../vms/
1010
MOUNTPATH=/mnt/cloud/systemvm
1111
TMPDIR=${TMP}/cloud/systemvm
@@ -17,31 +17,31 @@ inject_into_iso() {
1717
local backup=${isofile}.bak
1818
local tmpiso=${TMP}/$1
1919
[ ! -f $isofile ] && echo "$(basename $0): Could not find systemvm iso patch file $isofile" && return 1
20-
mount -o loop $isofile $MOUNTPATH
20+
sudo mount -o loop $isofile $MOUNTPATH
2121
[ $? -ne 0 ] && echo "$(basename $0): Failed to mount original iso $isofile" && return 1
2222
diff -q $MOUNTPATH/authorized_keys $newpubkey &> /dev/null && return 0
23-
cp -b $isofile $backup
23+
sudo cp -b $isofile $backup
2424
[ $? -ne 0 ] && echo "$(basename $0): Failed to backup original iso $isofile" && return 1
2525
rm -rf $TMPDIR
2626
mkdir -p $TMPDIR
2727
[ ! -d $TMPDIR ] && echo "$(basename $0): Could not find/create temporary dir $TMPDIR" && return 1
28-
cp -fr $MOUNTPATH/* $TMPDIR/
28+
sudo cp -fr $MOUNTPATH/* $TMPDIR/
2929
[ $? -ne 0 ] && echo "$(basename $0): Failed to copy from original iso $isofile" && return 1
30-
cp $newpubkey $TMPDIR/authorized_keys
30+
sudo cp $newpubkey $TMPDIR/authorized_keys
3131
[ $? -ne 0 ] && echo "$(basename $0): Failed to copy key $newpubkey from original iso to new iso " && return 1
3232
mkisofs -quiet -r -o $tmpiso $TMPDIR
3333
[ $? -ne 0 ] && echo "$(basename $0): Failed to create new iso $tmpiso from $TMPDIR" && return 1
34-
umount $MOUNTPATH
34+
sudo umount $MOUNTPATH
3535
[ $? -ne 0 ] && echo "$(basename $0): Failed to unmount old iso from $MOUNTPATH" && return 1
36-
cp -f $tmpiso $isofile
36+
sudo cp -f $tmpiso $isofile
3737
[ $? -ne 0 ] && echo "$(basename $0): Failed to overwrite old iso $isofile with $tmpiso" && return 1
3838
rm -rf $TMPDIR
3939
}
4040

4141
copy_priv_key() {
4242
local newprivkey=$1
4343
diff -q $newprivkey $(dirname $0)/id_rsa.cloud && return 0
44-
cp -fb $newprivkey $(dirname $0)/id_rsa.cloud && chmod 0600 $(dirname $0)/id_rsa.cloud
44+
sudo cp -fb $newprivkey $(dirname $0)/id_rsa.cloud
4545
return $?
4646
}
4747

@@ -52,7 +52,6 @@ newpubkey=$1
5252
newprivkey=$2
5353
[ ! -f $newpubkey ] && echo "$(basename $0): Could not open $newpubkey" && exit 3
5454
[ ! -f $newprivkey ] && echo "$(basename $0): Could not open $newprivkey" && exit 3
55-
[ $EUID -ne 0 ] && echo "$(basename $0): You have to be root to run this script" && exit 3
5655

5756
command -v mkisofs > /dev/null || (echo "$(basename $0): mkisofs not found, please install or ensure PATH is accurate" ; exit 4)
5857

scripts/vm/systemvm/injectkeys2.sh

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
#!/bin/bash
2+
# Copies keys that enable SSH communication with system vms
3+
# $1 = new public key
4+
# $2 = new private key
5+
6+
set -x
7+
8+
TMP=${HOME}/tmp
9+
SYSTEMVM_PATCH_DIR=../../../vms/
10+
MOUNTPATH=/mnt/cloud/systemvm
11+
TMPDIR=${TMP}/cloud/systemvm
12+
13+
14+
inject_into_iso() {
15+
local isofile=${SYSTEMVM_PATCH_DIR}/$1
16+
local newpubkey=$2
17+
local backup=${isofile}.bak
18+
local tmpiso=${TMP}/$1
19+
[ ! -f $isofile ] && echo "$(basename $0): Could not find systemvm iso patch file $isofile" && return 1
20+
sudo mount -o loop $isofile $MOUNTPATH
21+
[ $? -ne 0 ] && echo "$(basename $0): Failed to mount original iso $isofile" && return 1
22+
diff -q $MOUNTPATH/authorized_keys $newpubkey &> /dev/null && return 0
23+
sudo cp -b $isofile $backup
24+
[ $? -ne 0 ] && echo "$(basename $0): Failed to backup original iso $isofile" && return 1
25+
rm -rf $TMPDIR
26+
mkdir -p $TMPDIR
27+
[ ! -d $TMPDIR ] && echo "$(basename $0): Could not find/create temporary dir $TMPDIR" && return 1
28+
sudo cp -fr $MOUNTPATH/* $TMPDIR/
29+
[ $? -ne 0 ] && echo "$(basename $0): Failed to copy from original iso $isofile" && return 1
30+
sudo cp $newpubkey $TMPDIR/authorized_keys
31+
[ $? -ne 0 ] && echo "$(basename $0): Failed to copy key $newpubkey from original iso to new iso " && return 1
32+
mkisofs -quiet -r -o $tmpiso $TMPDIR
33+
[ $? -ne 0 ] && echo "$(basename $0): Failed to create new iso $tmpiso from $TMPDIR" && return 1
34+
sudo umount $MOUNTPATH
35+
[ $? -ne 0 ] && echo "$(basename $0): Failed to unmount old iso from $MOUNTPATH" && return 1
36+
#cp -f $tmpiso $isofile
37+
#[ $? -ne 0 ] && echo "$(basename $0): Failed to overwrite old iso $isofile with $tmpiso" && return 1
38+
rm -rf $TMPDIR
39+
}
40+
41+
copy_priv_key() {
42+
local newprivkey=$1
43+
diff -q $newprivkey $(dirname $0)/id_rsa.cloud && return 0
44+
sudo cp -fb $newprivkey $(dirname $0)/id_rsa.cloud && sudo chmod 0600 $(dirname $0)/id_rsa.cloud
45+
return $?
46+
}
47+
48+
mkdir -p $MOUNTPATH
49+
50+
[ $# -ne 2 ] && echo "Usage: $(basename $0) <new public key file> <new private key file>" && exit 3
51+
newpubkey=$1
52+
newprivkey=$2
53+
[ ! -f $newpubkey ] && echo "$(basename $0): Could not open $newpubkey" && exit 3
54+
[ ! -f $newprivkey ] && echo "$(basename $0): Could not open $newprivkey" && exit 3
55+
56+
command -v mkisofs > /dev/null || (echo "$(basename $0): mkisofs not found, please install or ensure PATH is accurate" ; exit 4)
57+
58+
inject_into_iso systemvm.iso $newpubkey
59+
#inject_into_iso systemvm-premium.iso $newpubkey
60+
61+
[ $? -ne 0 ] && exit 5
62+
63+
copy_priv_key $newprivkey
64+
65+
exit $?

server/src/com/cloud/server/ConfigurationServerImpl.java

Lines changed: 62 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
import java.io.EOFException;
2323
import java.io.File;
2424
import java.io.FileInputStream;
25+
import java.io.FileNotFoundException;
26+
import java.io.FileOutputStream;
2527
import java.io.IOException;
2628
import java.math.BigInteger;
2729
import java.net.NetworkInterface;
@@ -30,6 +32,7 @@
3032
import java.security.NoSuchAlgorithmException;
3133
import java.sql.PreparedStatement;
3234
import java.sql.SQLException;
35+
import java.util.ArrayList;
3336
import java.util.HashMap;
3437
import java.util.List;
3538
import java.util.Properties;
@@ -393,29 +396,28 @@ protected void updateKeyPairs() {
393396
s_logger.info("Processing updateKeyPairs");
394397
}
395398
String already = _configDao.getValue("ssh.privatekey");
399+
String homeDir = Script.runSimpleBashScript("echo ~");
400+
String userid = System.getProperty("user.name");
401+
if (homeDir == "~") {
402+
s_logger.error("No home directory was detected. Set the HOME environment variable to point to your user profile or home directory.");
403+
throw new CloudRuntimeException("No home directory was detected. Set the HOME environment variable to point to your user profile or home directory.");
404+
}
405+
File privkeyfile = new File(homeDir + "/.ssh/id_rsa");
406+
File pubkeyfile = new File(homeDir + "/.ssh/id_rsa.pub");
396407

397408
if (already == null || already.isEmpty()) {
398409
if (s_logger.isInfoEnabled()) {
399410
s_logger.info("Need to store in the database");
400411
}
412+
Script.runSimpleBashScript("if [ -f ~/.ssh/id_rsa ] ; then true ; else yes '' | ssh-keygen -t rsa -q ; fi");
401413

402-
String homeDir = Script.runSimpleBashScript("echo ~");
403-
if (homeDir == "~") {
404-
s_logger.error("No home directory was detected. Set the HOME environment variable to point to your user profile or home directory.");
405-
throw new RuntimeException("No home directory was detected. Set the HOME environment variable to point to your user profile or home directory.");
406-
}
407-
408-
String keygenOutput = Script.runSimpleBashScript("if [ -f ~/.ssh/id_rsa ] ; then true ; else yes '' | ssh-keygen -t rsa -q ; fi");
409-
410-
File privkeyfile = new File(homeDir + "/.ssh/id_rsa");
411-
File pubkeyfile = new File(homeDir + "/.ssh/id_rsa.pub");
412414
byte[] arr1 = new byte[4094]; // configuration table column value size
413415
try {
414416
new DataInputStream(new FileInputStream(privkeyfile)).readFully(arr1);
415417
} catch (EOFException e) {
416418
} catch (Exception e) {
417419
s_logger.error("Cannot read the private key file",e);
418-
throw new RuntimeException("Cannot read the private key file");
420+
throw new CloudRuntimeException("Cannot read the private key file");
419421
}
420422
String privateKey = new String(arr1).trim();
421423
byte[] arr2 = new byte[4094]; // configuration table column value size
@@ -424,7 +426,7 @@ protected void updateKeyPairs() {
424426
} catch (EOFException e) {
425427
} catch (Exception e) {
426428
s_logger.warn("Cannot read the public key file",e);
427-
throw new RuntimeException("Cannot read the public key file");
429+
throw new CloudRuntimeException("Cannot read the public key file");
428430
}
429431
String publicKey = new String(arr2).trim();
430432

@@ -442,7 +444,7 @@ protected void updateKeyPairs() {
442444
}
443445
} catch (SQLException ex) {
444446
s_logger.error("SQL of the private key failed",ex);
445-
throw new RuntimeException("SQL of the private key failed");
447+
throw new CloudRuntimeException("SQL of the private key failed");
446448
}
447449

448450
try {
@@ -453,26 +455,70 @@ protected void updateKeyPairs() {
453455
}
454456
} catch (SQLException ex) {
455457
s_logger.error("SQL of the public key failed",ex);
456-
throw new RuntimeException("SQL of the public key failed");
458+
throw new CloudRuntimeException("SQL of the public key failed");
457459
}
458-
injectSshKeyIntoSystemVmIsoPatch(pubkeyfile.getAbsolutePath());
460+
459461
if (s_logger.isDebugEnabled()) {
460462
s_logger.debug("Public key inserted into systemvm iso");
461463
}
462464
} else {
463465
s_logger.info("Keypairs already in database");
466+
if (userid.startsWith("cloud")) {
467+
s_logger.info("Keypairs already in database, updating local copy");
468+
updateKeyPairsOnDisk(homeDir);
469+
}
470+
}
471+
if (userid.startsWith("cloud")){
472+
s_logger.info("Going to update systemvm iso with generated keypairs if needed");
473+
injectSshKeysIntoSystemVmIsoPatch(pubkeyfile.getAbsolutePath(), privkeyfile.getAbsolutePath());
474+
}
475+
}
476+
477+
private void writeKeyToDisk(String key, String keyPath) {
478+
479+
File keyfile = new File( keyPath);
480+
if (!keyfile.exists()) {
481+
try {
482+
keyfile.createNewFile();
483+
} catch (IOException e) {
484+
s_logger.warn("Failed to create file: " + e.toString());
485+
throw new CloudRuntimeException("Failed to update keypairs on disk: cannot create key file " + keyPath);
486+
}
487+
}
488+
489+
if (keyfile.exists()) {
490+
try {
491+
FileOutputStream kStream = new FileOutputStream(keyfile);
492+
kStream.write(key.getBytes());
493+
kStream.close();
494+
} catch (FileNotFoundException e) {
495+
s_logger.warn("Failed to write key to " + keyfile.getAbsolutePath());
496+
throw new CloudRuntimeException("Failed to update keypairs on disk: cannot find key file " + keyPath);
497+
} catch (IOException e) {
498+
s_logger.warn("Failed to write key to " + keyfile.getAbsolutePath());
499+
throw new CloudRuntimeException("Failed to update keypairs on disk: cannot write to key file " + keyPath);
500+
}
464501
}
502+
465503
}
466504

505+
private void updateKeyPairsOnDisk(String homeDir ) {
506+
507+
String pubKey = _configDao.getValue("ssh.publickey");
508+
String prvKey = _configDao.getValue("ssh.privatekey");
509+
writeKeyToDisk(homeDir + "/.ssh/id_rsa", prvKey);
510+
writeKeyToDisk(homeDir + "/.ssh/id_rsa.pub", pubKey);
511+
}
467512

468-
protected void injectSshKeyIntoSystemVmIsoPatch(String publicKeyPath) {
513+
protected void injectSshKeysIntoSystemVmIsoPatch(String publicKeyPath, String privKeyPath) {
469514
String injectScript = "scripts/vm/systemvm/injectkeys.sh";
470515
String scriptPath = Script.findScript("" , injectScript);
471516
if ( scriptPath == null ) {
472517
throw new CloudRuntimeException("Unable to find key inject script " + injectScript);
473518
}
474519
final Script command = new Script(scriptPath, s_logger);
475520
command.add(publicKeyPath);
521+
command.add(privKeyPath);
476522

477523
final String result = command.execute();
478524
if (result != null) {

0 commit comments

Comments
 (0)