1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-03-22 18:50:08 +03:00

Merge branch 'feature-200' of dsa-research.org:one into feature-200

This commit is contained in:
Tino Vázquez 2010-06-30 18:02:21 +02:00
commit ed48b53497
6 changed files with 381 additions and 133 deletions

View File

@ -19,6 +19,7 @@
#include "PoolSQL.h"
#include "ImageTemplate.h"
#include "NebulaLog.h"
using namespace std;
@ -367,6 +368,14 @@ private:
db->exec(oss_templ);
};
/**
* "Encrypts" the password with SHA1 digest
* @param password
* @return sha1 encrypted password
*/
string sha1_digest(const string& pass);
protected:
// *************************************************************************

View File

@ -194,26 +194,47 @@ public:
return rc;
}
private:
/**
* This map stores the association between IIDs and Image names
*/
map<string, int> image_names;
static const string& source_prefix()
{
return _source_prefix;
};
static const string& default_type()
{
return _default_type;
};
static const string& default_dev_prefix()
{
return _default_dev_prefix;
};
private:
//--------------------------------------------------------------------------
// Configuration Attributes for Images
// -------------------------------------------------------------------------
/**
* Path to the image repository
**/
string source_prefix;
static string _source_prefix;
/**
* Default image type
**/
string default_type;
static string _default_type;
/**
* Default device prefix
**/
string default_dev_prefix;
static string _default_dev_prefix;
//--------------------------------------------------------------------------
// Pool Attributes
// -------------------------------------------------------------------------
/**
* This map stores the association between IIDs and Image names
*/
map<string, int> image_names;
/**
* Factory method to produce Image objects
@ -243,12 +264,6 @@ private:
*/
int init_cb(void *nil, int num, char **values, char **names);
/**
* "Encrypts" the password with SHA1 digest
* @param password
* @return sha1 encrypted password
*/
string sha1_digest(const string& pass);
};
#endif /*IMAGE_POOL_H_*/

83
share/hooks/image.rb Executable file
View File

@ -0,0 +1,83 @@
#!/usr/bin/env ruby
# -------------------------------------------------------------------------- #
# Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org) #
# #
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
# not use this file except in compliance with the License. You may obtain #
# a copy of the License at #
# #
# http://www.apache.org/licenses/LICENSE-2.0 #
# #
# Unless required by applicable law or agreed to in writing, software #
# distributed under the License is distributed on an "AS IS" BASIS, #
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
# See the License for the specific language governing permissions and #
# limitations under the License. #
#--------------------------------------------------------------------------- #
ONE_LOCATION=ENV["ONE_LOCATION"]
if !ONE_LOCATION
RUBY_LIB_LOCATION="/usr/lib/one/ruby"
VMDIR="/var/lib/one"
else
RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby"
VMDIR=ONE_LOCATION+"/var"
end
$: << RUBY_LIB_LOCATION
require 'OpenNebula'
require 'client_utilities'
require 'pp'
if !(vm_id=ARGV[0])
exit -1
end
vm=OpenNebula::VirtualMachine.new_with_id(vm_id, get_one_client)
vm.info
template=vm.to_hash
template=template['VM']['TEMPLATE']
disks=[template['DISK']].flatten if template['DISK']
disks.each_with_index do |disk,i|
source_path=VMDIR+"/#{vm_id}/disk.#{i}"
if disk["NAME"]# and File.exists?(source_path)
if nil#disk["SAVE_AS"]
# Perform the allocate if all goes well
image=OpenNebula::Image.new(
OpenNebula::Image.build_xml, get_one_client)
begin
template="NAME=#{disk['SAVE_AS']}\n"
template+="TYPE=#{disk['TYPE'].upcase}\n" if DISK["TYPE"]
result=image.allocate(template)
rescue
result=OpenNebula::Error.new("Error in template")
end
# Get the allocated image
image=OpenNebula::Image.new_with_id(image.id, get_one_client)
image.info
template=image.to_hash
template=template['IMAGE']['TEMPLATE']
if !is_successful?(result)
exit -1
end
elsif disk["OVERWRITE"]
# Get the allocated image
image=OpenNebula::Image.new_with_id(disk['IID'], get_one_client)
image.info
image.disable
end
# Perform the copy to the image repo if needed
if File.copy(source_path, image['SOURCE'])
result=image.enable
else
result=OpenNebula::Error.new(
"Cannot copy image, please update before enabling it.")
end
end
end

View File

@ -19,6 +19,8 @@
#include <iostream>
#include <sstream>
#include <openssl/evp.h>
#include <iomanip>
#include "Image.h"
#include "ImagePool.h"
@ -137,6 +139,76 @@ int Image::insert(SqlDB *db)
{
int rc;
string source_att;
string type_att;
string public_attr;
string dev_prefix;
ostringstream tmp_hashstream;
ostringstream tmp_sourcestream;
// ---------------------------------------------------------------------
// Check default image attributes
// ---------------------------------------------------------------------
// ------------ NAME --------------------
get_template_attribute("NAME", name);
if ( name.empty() == true )
{
goto error_name;
}
// ------------ TYPE --------------------
get_template_attribute("TYPE", type_att);
transform (type_att.begin(), type_att.end(), type_att.begin(),
(int(*)(int))toupper);
if ( type_att.empty() == true )
{
type_att = ImagePool::default_type();
}
if (set_type(type_att) != 0)
{
goto error_type;
}
// ------------ PUBLIC --------------------
get_template_attribute("PUBLIC", public_attr);
transform (public_attr.begin(), public_attr.end(), public_attr.begin(),
(int(*)(int))toupper);
public_img = (public_attr == "YES");
// ------------ PREFIX --------------------
get_template_attribute("DEV_PREFIX", dev_prefix);
if( dev_prefix.empty() )
{
SingleAttribute * dev_att = new SingleAttribute("DEV_PREFIX",
ImagePool::default_dev_prefix());
image_template.set(dev_att);
}
// ------------ SOURCE (path to store the image)--------------------
tmp_hashstream << uid << ":" << name;
tmp_sourcestream << ImagePool::source_prefix() << "/";
tmp_sourcestream << sha1_digest(tmp_hashstream.str());
source = tmp_sourcestream.str();
// Set up the template ID, to insert it
if ( image_template.id == -1 )
{
@ -164,6 +236,15 @@ int Image::insert(SqlDB *db)
}
return 0;
error_name:
NebulaLog::log("IMG", Log::ERROR, "NAME not present in image template");
goto error_common;
error_type:
NebulaLog::log("IMG", Log::ERROR, "Incorrect TYPE in image template");
goto error_common;
error_common:
return -1;
}
/* ------------------------------------------------------------------------ */
@ -583,6 +664,33 @@ int Image::disk_attribute(VectorAttribute * disk, int * index)
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
string Image::sha1_digest(const string& pass)
{
EVP_MD_CTX mdctx;
unsigned char md_value[EVP_MAX_MD_SIZE];
unsigned int md_len;
ostringstream oss;
EVP_MD_CTX_init(&mdctx);
EVP_DigestInit_ex(&mdctx, EVP_sha1(), NULL);
EVP_DigestUpdate(&mdctx, pass.c_str(), pass.length());
EVP_DigestFinal_ex(&mdctx,md_value,&md_len);
EVP_MD_CTX_cleanup(&mdctx);
for(unsigned int i = 0; i<md_len; i++)
{
oss << setfill('0') << setw(2) << hex << nouppercase
<< (unsigned short) md_value[i];
}
return oss.str();
}
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */

View File

@ -19,11 +19,12 @@
/* ************************************************************************** */
#include "ImagePool.h"
#include <openssl/evp.h>
#include <iomanip>
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
string ImagePool::_source_prefix;
string ImagePool::_default_type;
string ImagePool::_default_dev_prefix;
int ImagePool::init_cb(void *nil, int num, char **values, char **names)
{
@ -40,19 +41,22 @@ int ImagePool::init_cb(void *nil, int num, char **values, char **names)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
ImagePool::ImagePool( SqlDB * db,
const string& _source_prefix,
const string& _default_type,
const string& _default_dev_prefix):
PoolSQL(db,Image::table),
source_prefix(_source_prefix),
default_type(_default_type),
default_dev_prefix(_default_dev_prefix)
ImagePool::ImagePool( SqlDB * db,
const string& __source_prefix,
const string& __default_type,
const string& __default_dev_prefix):
PoolSQL(db,Image::table)
{
ostringstream sql;
int rc;
// Init static defaults
_source_prefix = __source_prefix;
_default_type = __default_type;
_default_dev_prefix = __default_dev_prefix;
// Set default type
if (_default_type != "OS" &&
_default_type != "CDROM" &&
@ -60,7 +64,7 @@ ImagePool::ImagePool( SqlDB * db,
{
NebulaLog::log("IMG", Log::ERROR,
"Bad default for image type, setting OS");
default_type = "OS";
_default_type = "OS";
}
// Read from the DB the existing images, and build the ID:Name map
@ -87,18 +91,11 @@ int ImagePool::allocate (
const string& stemplate,
int * oid)
{
Image * img;
string name;
string source;
string type;
string public_attr;
string dev_prefix;
char * error_msg;
int rc;
Image * img;
ostringstream tmp_hashstream;
ostringstream tmp_sourcestream;
string name;
char * error_msg;
// ---------------------------------------------------------------------
// Build a new Image object
@ -115,68 +112,8 @@ int ImagePool::allocate (
goto error_parse;
}
// ---------------------------------------------------------------------
// Check default image attributes
// ---------------------------------------------------------------------
// ------------ NAME --------------------
img->get_template_attribute("NAME", name);
if ( name.empty() == true )
{
goto error_name;
}
img->name = name;
// ------------ TYPE --------------------
img->get_template_attribute("TYPE", type);
transform (type.begin(), type.end(), type.begin(),
(int(*)(int))toupper);
if ( type.empty() == true )
{
type = default_type;
}
if (img->set_type(type) != 0)
{
goto error_type;
}
// ------------ PUBLIC --------------------
img->get_template_attribute("PUBLIC", public_attr);
transform (public_attr.begin(), public_attr.end(), public_attr.begin(),
(int(*)(int))toupper);
img->public_img = (public_attr == "YES");
// ------------ PREFIX --------------------
img->get_template_attribute("DEV_PREFIX", dev_prefix);
if( dev_prefix.empty() )
{
SingleAttribute * dev_att =
new SingleAttribute("DEV_PREFIX", default_dev_prefix);
img->image_template.set(dev_att);
}
// ------------ SOURCE (path to store the image)--------------------
tmp_hashstream << uid << ":" << name;
tmp_sourcestream << source_prefix << "/";
tmp_sourcestream << sha1_digest(tmp_hashstream.str());
img->source = tmp_sourcestream.str();
// ---------------------------------------------------------------------
// Insert the Object in the pool
// ---------------------------------------------------------------------
@ -196,17 +133,6 @@ int ImagePool::allocate (
return *oid;
error_name:
NebulaLog::log("IMG", Log::ERROR, "NAME not present in image template");
goto error_common;
error_type:
NebulaLog::log("IMG", Log::ERROR, "Incorrect TYPE in image template");
goto error_common;
error_common:
delete img;
*oid = -1;
return -1;
error_parse:
ostringstream oss;
oss << "ImagePool template parse error: " << error_msg;
@ -263,30 +189,3 @@ int ImagePool::dump(ostringstream& oss, const string& where)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
string ImagePool::sha1_digest(const string& pass)
{
EVP_MD_CTX mdctx;
unsigned char md_value[EVP_MAX_MD_SIZE];
unsigned int md_len;
ostringstream oss;
EVP_MD_CTX_init(&mdctx);
EVP_DigestInit_ex(&mdctx, EVP_sha1(), NULL);
EVP_DigestUpdate(&mdctx, pass.c_str(), pass.length());
EVP_DigestFinal_ex(&mdctx,md_value,&md_len);
EVP_MD_CTX_cleanup(&mdctx);
for(unsigned int i = 0; i<md_len; i++)
{
oss << setfill('0') << setw(2) << hex << nouppercase
<< (unsigned short) md_value[i];
}
return oss.str();
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

View File

@ -85,6 +85,7 @@ class ImagePoolTest : public PoolTest
CPPUNIT_TEST ( target_generation );
CPPUNIT_TEST ( bus_source_assignment );
CPPUNIT_TEST ( public_attribute );
CPPUNIT_TEST ( disk_overwrite );
CPPUNIT_TEST ( dump );
CPPUNIT_TEST ( dump_where );
@ -156,6 +157,7 @@ protected:
delete user_pool;
};
public:
ImagePoolTest(){};
@ -292,6 +294,8 @@ public:
check(1, obj);
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void wrong_get_name()
{
@ -548,6 +552,136 @@ public:
delete disk;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void disk_overwrite()
{
ImagePool * imp = static_cast<ImagePool *>(pool);
Image * img;
VectorAttribute * disk;
int oid, rc;
string value;
int index = 0;
// ---------------------------------------------------------------------
// Allocate an OS type image
oid = allocate(0);
CPPUNIT_ASSERT( oid > -1 );
img = imp->get(oid, false);
// Disk with overwrite=yes, save_as empty
disk = new VectorAttribute("DISK");
disk->replace("OVERWRITE", "yes");
img->enable(true);
rc = img->disk_attribute(disk, &index);
CPPUNIT_ASSERT( rc == 0 );
value = disk->vector_value("OVERWRITE");
CPPUNIT_ASSERT( value == "YES" );
value = "";
value = disk->vector_value("SAVE_AS");
CPPUNIT_ASSERT( value == "" );
value = "";
value = disk->vector_value("CLONE");
CPPUNIT_ASSERT( value == "NO" );
value = "";
value = disk->vector_value("SAVE");
CPPUNIT_ASSERT( value == "YES" );
value = "";
value = disk->vector_value("READONLY");
CPPUNIT_ASSERT( value == "NO" );
// clean up
delete disk;
// ---------------------------------------------------------------------
// Allocate an OS type image
oid = allocate(1);
CPPUNIT_ASSERT( oid > -1 );
img = imp->get(oid, false);
// Disk with overwrite=no, save_as not empty
disk = new VectorAttribute("DISK");
disk->replace("OVERWRITE", "NO");
disk->replace("SAVE_AS", "path_to_save");
img->enable(true);
rc = img->disk_attribute(disk, &index);
CPPUNIT_ASSERT( rc == 0 );
value = "";
value = disk->vector_value("OVERWRITE");
CPPUNIT_ASSERT( value == "NO" );
value = "";
value = disk->vector_value("SAVE_AS");
CPPUNIT_ASSERT( value == "path_to_save" );
value = "";
value = disk->vector_value("CLONE");
CPPUNIT_ASSERT( value == "YES" );
value = "";
value = disk->vector_value("SAVE");
CPPUNIT_ASSERT( value == "YES" );
value = "";
value = disk->vector_value("READONLY");
CPPUNIT_ASSERT( value == "NO" );
// clean up
delete disk;
// ---------------------------------------------------------------------
// Allocate an OS type image
oid = allocate(2);
CPPUNIT_ASSERT( oid > -1 );
img = imp->get(oid, false);
// Disk with overwrite=no, save_as not present
disk = new VectorAttribute("DISK");
disk->replace("OVERWRITE", "NO");
img->enable(true);
rc = img->disk_attribute(disk, &index);
CPPUNIT_ASSERT( rc == 0 );
value = "";
value = disk->vector_value("OVERWRITE");
CPPUNIT_ASSERT( value == "NO" );
value = "";
value = disk->vector_value("SAVE_AS");
CPPUNIT_ASSERT( value == "" );
value = "";
value = disk->vector_value("CLONE");
CPPUNIT_ASSERT( value == "YES" );
value = "";
value = disk->vector_value("SAVE");
CPPUNIT_ASSERT( value == "NO" );
value = "";
value = disk->vector_value("READONLY");
CPPUNIT_ASSERT( value == "NO" );
// clean up
delete disk;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */