From 1561c7d2f98867eedffc6edde39e6e27f548275c Mon Sep 17 00:00:00 2001 From: alena Date: Thu, 22 Sep 2011 11:00:06 -0700 Subject: [PATCH] bug 11468: create ROOT domain and admin user as a part of cloud-setup-databases, not during the management server startup to avoid multiple records insertion for the same domain status 11468: resolved fixed Reviewed-by: will@cloud.com Conflicts: server/src/com/cloud/server/ConfigurationServerImpl.java --- .../cloud/server/ConfigurationServerImpl.java | 154 ++---------------- server/src/com/cloud/test/DatabaseConfig.java | 116 +++++++++++++ 2 files changed, 131 insertions(+), 139 deletions(-) diff --git a/server/src/com/cloud/server/ConfigurationServerImpl.java b/server/src/com/cloud/server/ConfigurationServerImpl.java index ed98ba3893c..a1eafd90d0f 100644 --- a/server/src/com/cloud/server/ConfigurationServerImpl.java +++ b/server/src/com/cloud/server/ConfigurationServerImpl.java @@ -25,13 +25,10 @@ import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; -import java.math.BigInteger; import java.net.InetAddress; import java.net.UnknownHostException; -import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.sql.PreparedStatement; -import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.HashMap; @@ -88,7 +85,6 @@ import com.cloud.test.IPRangeConfig; import com.cloud.user.Account; import com.cloud.user.AccountVO; import com.cloud.user.User; -import com.cloud.user.UserVO; import com.cloud.user.dao.AccountDao; import com.cloud.user.dao.UserDao; import com.cloud.utils.PasswordGenerator; @@ -148,13 +144,8 @@ public class ConfigurationServerImpl implements ConfigurationServer { if (init == null || init.equals("false")) { s_logger.debug("ConfigurationServer is saving default values to the database."); - Transaction txn = Transaction.currentTxn(); - txn.start(); - // Create ROOT domain - saveRootDomain(); - - // Create system user and admin user - saveUser(); + Transaction txn = Transaction.currentTxn(); + txn.start(); // Save default Configuration Table values List categories = Config.getCategories(); @@ -292,117 +283,6 @@ public class ConfigurationServerImpl implements ConfigurationServer { return null; } } - - - @DB - protected void saveUser() { - // insert system account - String insertSql = "INSERT INTO `cloud`.`account` (id, account_name, type, domain_id) VALUES (1, 'system', '1', '1')"; - Transaction txn = Transaction.currentTxn(); - txn.start(); - - //Create system/admin accounts - AccountVO systemAccount = new AccountVO(1); - systemAccount.setAccountName("system"); - systemAccount.setType(Account.ACCOUNT_TYPE_ADMIN);; - systemAccount.setDomainId(1); - systemAccount.setState(Account.State.enabled); - _accountDao.persist(systemAccount); - - AccountVO adminAccount = new AccountVO(1); - adminAccount.setAccountName("admin"); - adminAccount.setType(Account.ACCOUNT_TYPE_ADMIN);; - adminAccount.setDomainId(1); - adminAccount.setState(Account.State.enabled); - _accountDao.persist(adminAccount); - - //Create system/admin users - MessageDigest md5 = null; - try { - md5 = MessageDigest.getInstance("MD5"); - } catch (NoSuchAlgorithmException e) { - return; - } - - String password = "password"; - md5.reset(); - BigInteger pwInt = new BigInteger(1, md5.digest(password.getBytes())); - String pwStr = pwInt.toString(16); - int padding = 32 - pwStr.length(); - StringBuffer sb = new StringBuffer(); - for (int i = 0; i < padding; i++) { - sb.append('0'); // make sure the MD5 password is 32 digits long - } - sb.append(pwStr); - password = sb.toString(); - - UserVO systemUser = new UserVO(1); - systemUser.setUsername("system"); - systemUser.setPassword(""); - systemUser.setAccountId(1); - systemUser.setFirstname("system"); - systemUser.setLastname("system"); - systemUser.setState(Account.State.enabled); - _userDao.persist(systemUser); - - - UserVO adminUser = new UserVO(2); - adminUser.setUsername("admin"); - adminUser.setPassword(password); - adminUser.setAccountId(2); - adminUser.setFirstname("admin"); - adminUser.setLastname("cloud"); - adminUser.setState(Account.State.enabled); - _userDao.persist(adminUser); - - - //create resource counts - try { - _resourceCountDao.createResourceCounts(1, ResourceOwnerType.Account); - _resourceCountDao.createResourceCounts(2, ResourceOwnerType.Account); - } catch (Exception ex) { - // if exception happens, it might mean that resource counts are already created by another management server being started in the cluster - s_logger.warn("Failed to create initial resource counts for system/admin accounts"); - } - - try { - String tableName = "security_group"; - try { - String checkSql = "SELECT * from network_group"; - PreparedStatement stmt = txn.prepareAutoCloseStatement(checkSql); - stmt.executeQuery(); - tableName = "network_group"; - } catch (Exception ex) { - // if network_groups table exists, create the default security group there - } - - insertSql = "SELECT * FROM " + tableName + " where account_id=2 and name='default'"; - PreparedStatement stmt = txn.prepareAutoCloseStatement(insertSql); - ResultSet rs = stmt.executeQuery(); - if (!rs.next()) { - //save default security group - if (tableName.equals("security_group")) { - insertSql = "INSERT INTO " + tableName +" (name, description, account_id, domain_id) " + - "VALUES ('default', 'Default Security Group', 2, 1)"; - } else { - insertSql = "INSERT INTO " + tableName +" (name, description, account_id, domain_id, account_name) " + - "VALUES ('default', 'Default Security Group', 2, 1, 'admin')"; - } - - try { - stmt = txn.prepareAutoCloseStatement(insertSql); - stmt.executeUpdate(); - } catch (SQLException ex) { - s_logger.warn("Failed to create default security group for default admin account due to ", ex); - } - } - rs.close(); - } catch (Exception ex) { - s_logger.warn("Failed to create default security group for default admin account due to ", ex); - } finally { - txn.commit(); - } - } protected void updateCloudIdentifier() { // Creates and saves a UUID as the cloud identifier @@ -971,24 +851,10 @@ public class ConfigurationServerImpl implements ConfigurationServer { } return networks.get(0).getId(); } - - @DB - public void saveRootDomain() { - Transaction txn = Transaction.currentTxn(); - txn.start(); - - DomainVO domain = new DomainVO(1, "ROOT", 2, null, null); - domain.setPath("/"); - domain.setLevel(0); - _domainDao.persist(domain); - _resourceCountDao.createResourceCounts(1, ResourceOwnerType.Domain); - - txn.commit(); - } - private void updateResourceCount() { + @DB + public void updateResourceCount() { ResourceType[] resourceTypes = Resource.ResourceType.values(); - List accounts = _accountDao.listAllIncludingRemoved(); List domains = _domainDao.listAllIncludingRemoved(); List domainResourceCount = _resourceCountDao.listResourceCountByOwnerType(ResourceOwnerType.Domain); @@ -1013,6 +879,10 @@ public class ConfigurationServerImpl implements ConfigurationServer { if ((domainResourceCount.size() < domainExpectedCount * domains.size())) { s_logger.debug("resource_count table has records missing for some domains...going to insert them"); for (DomainVO domain : domains) { + //Lock domain + Transaction txn = Transaction.currentTxn(); + txn.start(); + _domainDao.lockRow(domain.getId(), true); List domainCounts = _resourceCountDao.listByOwnerId(domain.getId(), ResourceOwnerType.Domain); List domainCountStr = new ArrayList(); for (ResourceCountVO domainCount : domainCounts) { @@ -1028,12 +898,17 @@ public class ConfigurationServerImpl implements ConfigurationServer { } } } + txn.commit(); } } if ((accountResourceCount.size() < accountExpectedCount * accounts.size())) { s_logger.debug("resource_count table has records missing for some accounts...going to insert them"); for (AccountVO account : accounts) { + //lock account + Transaction txn = Transaction.currentTxn(); + txn.start(); + _accountDao.lockRow(account.getId(), true); List accountCounts = _resourceCountDao.listByOwnerId(account.getId(), ResourceOwnerType.Account); List accountCountStr = new ArrayList(); for (ResourceCountVO accountCount : accountCounts) { @@ -1049,8 +924,9 @@ public class ConfigurationServerImpl implements ConfigurationServer { } } } + + txn.commit(); } - } } } diff --git a/server/src/com/cloud/test/DatabaseConfig.java b/server/src/com/cloud/test/DatabaseConfig.java index dda0fc526a3..8458d49302f 100755 --- a/server/src/com/cloud/test/DatabaseConfig.java +++ b/server/src/com/cloud/test/DatabaseConfig.java @@ -20,7 +20,10 @@ package com.cloud.test; import java.io.File; import java.io.IOException; +import java.math.BigInteger; import java.net.URISyntaxException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; import java.sql.Date; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -407,6 +410,7 @@ public class DatabaseConfig { // Save default values for configuration fields saveVMTemplate(); + saveRootDomain(); saveDefaultConfiguations(); txn.commit(); @@ -435,6 +439,8 @@ public class DatabaseConfig { saveServiceOffering(); } else if ("diskOffering".equals(_currentObjectName)) { saveDiskOffering(); + } else if ("user".equals(_currentObjectName)) { + saveUser(); } else if ("configuration".equals(_currentObjectName)) { saveConfiguration(); } else if ("storagePool".equals(_currentObjectName)) { @@ -959,6 +965,80 @@ public class DatabaseConfig { */ } + @DB + protected void saveUser() { + // insert system account + String insertSql = "INSERT INTO `cloud`.`account` (id, account_name, type, domain_id) VALUES (1, 'system', '1', '1')"; + Transaction txn = Transaction.currentTxn(); + try { + PreparedStatement stmt = txn.prepareAutoCloseStatement(insertSql); + stmt.executeUpdate(); + } catch (SQLException ex) { + s_logger.error("error creating system account", ex); + } + + // insert system user + insertSql = "INSERT INTO `cloud`.`user` (id, username, password, account_id, firstname, lastname, created) VALUES (1, 'system', '', 1, 'system', 'cloud', now())"; + txn = Transaction.currentTxn(); + try { + PreparedStatement stmt = txn.prepareAutoCloseStatement(insertSql); + stmt.executeUpdate(); + } catch (SQLException ex) { + s_logger.error("error creating system user", ex); + } + + // insert admin user + long id = Long.parseLong(_currentObjectParams.get("id")); + String username = _currentObjectParams.get("username"); + String firstname = _currentObjectParams.get("firstname"); + String lastname = _currentObjectParams.get("lastname"); + String password = _currentObjectParams.get("password"); + String email = _currentObjectParams.get("email"); + + if (email == null || email.equals("")) { + printError("An email address for each user is required."); + } + + MessageDigest md5 = null; + try { + md5 = MessageDigest.getInstance("MD5"); + } catch (NoSuchAlgorithmException e) { + s_logger.error("error saving user", e); + return; + } + md5.reset(); + BigInteger pwInt = new BigInteger(1, md5.digest(password.getBytes())); + String pwStr = pwInt.toString(16); + int padding = 32 - pwStr.length(); + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < padding; i++) { + sb.append('0'); // make sure the MD5 password is 32 digits long + } + sb.append(pwStr); + + // create an account for the admin user first + insertSql = "INSERT INTO `cloud`.`account` (id, account_name, type, domain_id) VALUES (" + id + ", '" + username + "', '1', '1')"; + txn = Transaction.currentTxn(); + try { + PreparedStatement stmt = txn.prepareAutoCloseStatement(insertSql); + stmt.executeUpdate(); + } catch (SQLException ex) { + s_logger.error("error creating account", ex); + } + + // now insert the user + insertSql = "INSERT INTO `cloud`.`user` (id, username, password, account_id, firstname, lastname, email, created) " + + "VALUES (" + id + ",'" + username + "','" + sb.toString() + "', 2, '" + firstname + "','" + lastname + "','" + email + "',now())"; + + txn = Transaction.currentTxn(); + try { + PreparedStatement stmt = txn.prepareAutoCloseStatement(insertSql); + stmt.executeUpdate(); + } catch (SQLException ex) { + s_logger.error("error creating user", ex); + } + } + private void saveDefaultConfiguations() { for (String name : s_defaultConfigurationValues.keySet()) { String value = s_defaultConfigurationValues.get(name); @@ -1046,6 +1126,42 @@ public class DatabaseConfig { return true; } + @DB + protected void saveRootDomain() { + String insertSql = "insert into `cloud`.`domain` (id, name, parent, owner, path, level) values (1, 'ROOT', NULL, 2, '/', 0)"; + Transaction txn = Transaction.currentTxn(); + try { + PreparedStatement stmt = txn.prepareAutoCloseStatement(insertSql); + stmt.executeUpdate(); + } catch (SQLException ex) { + s_logger.error("error creating ROOT domain", ex); + } + + /* + String updateSql = "update account set domain_id = 1 where id = 2"; + Transaction txn = Transaction.currentTxn(); + try { + PreparedStatement stmt = txn.prepareStatement(updateSql); + stmt.executeUpdate(); + } catch (SQLException ex) { + s_logger.error("error updating admin user", ex); + } finally { + txn.close(); + } + + updateSql = "update account set domain_id = 1 where id = 1"; + Transaction txn = Transaction.currentTxn(); + try { + PreparedStatement stmt = txn.prepareStatement(updateSql); + stmt.executeUpdate(); + } catch (SQLException ex) { + s_logger.error("error updating system user", ex); + } finally { + txn.close(); + } + */ + } + class DbConfigXMLHandler extends DefaultHandler { private DatabaseConfig _parent = null;