Statistics
| Branch: | Tag: | Revision:

one / src / rm / RequestManagerClone.cc @ 20deae85

History | View | Annotate | Download (7.57 KB)

1
/* -------------------------------------------------------------------------- */
2
/* Copyright 2002-2017, OpenNebula Project, OpenNebula Systems                */
3
/*                                                                            */
4
/* Licensed under the Apache License, Version 2.0 (the "License"); you may    */
5
/* not use this file except in compliance with the License. You may obtain    */
6
/* a copy of the License at                                                   */
7
/*                                                                            */
8
/* http://www.apache.org/licenses/LICENSE-2.0                                 */
9
/*                                                                            */
10
/* Unless required by applicable law or agreed to in writing, software        */
11
/* distributed under the License is distributed on an "AS IS" BASIS,          */
12
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   */
13
/* See the License for the specific language governing permissions and        */
14
/* limitations under the License.                                             */
15
/* -------------------------------------------------------------------------- */
16

    
17
#include "RequestManagerClone.h"
18
#include "RequestManagerImage.h"
19
#include "RequestManagerDelete.h"
20
#include "RequestManagerVMTemplate.h"
21
#include "PoolObjectAuth.h"
22
#include "Nebula.h"
23

    
24
/* -------------------------------------------------------------------------- */
25
/* -------------------------------------------------------------------------- */
26

    
27
void RequestManagerClone::request_execute(
28
        xmlrpc_c::paramList const&  paramList,
29
        RequestAttributes&          att)
30
{
31
    int    source_id = xmlrpc_c::value_int(paramList.getInt(1));
32
    string name      = xmlrpc_c::value_string(paramList.getString(2));
33
    bool   recursive = false;
34

    
35
    if (paramList.size() > 3)
36
    {
37
        recursive = xmlrpc_c::value_boolean(paramList.getBoolean(3));
38
    }
39

    
40
    int new_id;
41

    
42
    ErrorCode ec = clone(source_id, name, new_id, recursive, "", att);
43

    
44
    if ( ec == SUCCESS )
45
    {
46
        success_response(new_id, att);
47
    }
48
    else
49
    {
50
        failure_response(ec, att);
51
    }
52
}
53

    
54
/* -------------------------------------------------------------------------- */
55
/* -------------------------------------------------------------------------- */
56

    
57
Request::ErrorCode RequestManagerClone::clone(int source_id, const string &name,
58
        int &new_id, bool recursive, const string& s_uattr, RequestAttributes& att)
59
{
60
    int rc;
61
    PoolObjectAuth perms;
62

    
63
    PoolObjectSQL * source_obj = pool->get(source_id, true);
64

    
65
    if ( source_obj == 0 )
66
    {
67
        att.resp_id = source_id;
68
        return NO_EXISTS;
69
    }
70

    
71
    Template * tmpl = clone_template(source_obj);
72

    
73
    source_obj->get_permissions(perms);
74

    
75
    source_obj->unlock();
76

    
77
    ErrorCode ec = merge(tmpl, s_uattr, att);
78

    
79
    if (ec != SUCCESS)
80
    {
81
        delete tmpl;
82
        return ec;
83
    }
84

    
85
    tmpl->erase("NAME");
86
    tmpl->set(new SingleAttribute("NAME", name));
87

    
88
    if ( att.uid != 0 )
89
    {
90
        string tmpl_str = "";
91

    
92
        AuthRequest ar(att.uid, att.group_ids);
93

    
94
        ar.add_auth(auth_op, perms); //USE OBJECT
95

    
96
        tmpl->to_xml(tmpl_str);
97

    
98
        ar.add_create_auth(att.uid, att.gid, auth_object, tmpl_str);
99

    
100
        if (UserPool::authorize(ar) == -1)
101
        {
102
            att.resp_msg = ar.message;
103

    
104
            delete tmpl;
105
            return AUTHORIZATION;
106
        }
107
    }
108

    
109
    rc = pool_allocate(source_id, tmpl, new_id, att);
110

    
111
    if ( rc < 0 )
112
    {
113
        return ALLOCATE;
114
    }
115

    
116
    return SUCCESS;
117
}
118

    
119
/* -------------------------------------------------------------------------- */
120
/* -------------------------------------------------------------------------- */
121

    
122
Request::ErrorCode VMTemplateClone::clone(int source_id, const string &name,
123
        int &new_id, bool recursive, const string& s_uattr, RequestAttributes& att)
124
{
125
    // -------------------------------------------------------------------------
126
    // Clone the VMTemplate
127
    // -------------------------------------------------------------------------
128
    ErrorCode ec;
129

    
130
    ec = RequestManagerClone::clone(source_id, name, new_id, false, s_uattr, att);
131

    
132
    if ( ec != SUCCESS )
133
    {
134
        return ec;
135
    }
136
    else if ( !recursive )
137
    {
138
        return SUCCESS;
139
    }
140

    
141
    // -------------------------------------------------------------------------
142
    // Clone the template images when recursive flag is set
143
    // -------------------------------------------------------------------------
144
        ImageDelete     img_delete;
145
        ImageClone      img_clone;
146
    ImagePersistent img_persistent;
147

    
148
        TemplateDelete tmpl_delete;
149

    
150
    VMTemplatePool* tpool = static_cast<VMTemplatePool*>(pool);
151

    
152
    vector<int> new_ids;
153

    
154
    int ndisk = 0;
155
    vector<VectorAttribute *> vdisks;
156

    
157
    VirtualMachineDisks disks(false);
158
    VirtualMachineDisks::disk_iterator disk;
159

    
160
    RequestAttributes del_att(att);
161
    RequestAttributes img_att(att);
162
    img_att.resp_obj    = PoolObjectSQL::IMAGE;
163

    
164
    VMTemplate * vmtmpl = tpool->get(new_id, true);
165

    
166
    if (vmtmpl == 0)
167
    {
168
        att.resp_msg = "VM template was removed during clone operation";
169

    
170
        return ACTION;
171
    }
172

    
173
    vmtmpl->clone_disks(vdisks);
174

    
175
    vmtmpl->unlock();
176

    
177
    disks.init(vdisks, false);
178

    
179
    for ( disk = disks.begin(); disk != disks.end() ; ++disk )
180
    {
181
        int img_id;
182
        int new_img_id;
183

    
184
        if ( (*disk)->get_image_id(img_id, att.uid) == 0)
185
        {
186
            ostringstream oss;
187

    
188
            oss << name << "-disk-" << ndisk;
189

    
190
            ec = img_clone.request_execute(img_id,oss.str(),-1, new_img_id,img_att);
191

    
192
            if ( ec != SUCCESS)
193
            {
194
                NebulaLog::log("ReM", Log::ERROR, failure_message(ec, img_att));
195

    
196
                att.resp_msg = "Failed to clone images: " + img_att.resp_msg;
197

    
198
                goto error_images;
199
            }
200

    
201
            if ( (*disk)->is_managed() )
202
            {
203
                ec = img_persistent.request_execute(new_img_id, true, img_att);
204

    
205
                if (ec != SUCCESS)
206
                {
207
                    NebulaLog::log("ReM",Log::ERROR,failure_message(ec,img_att));
208

    
209
                    img_delete.request_execute(img_id, img_att);
210

    
211
                    att.resp_msg = "Failed to clone images: " + img_att.resp_msg;
212

    
213
                    goto error_images;
214
                }
215
            }
216

    
217
            (*disk)->remove("IMAGE");
218
            (*disk)->remove("IMAGE_UNAME");
219
            (*disk)->remove("IMAGE_UID");
220

    
221
            (*disk)->replace("IMAGE_ID", new_img_id);
222

    
223
            new_ids.push_back(new_img_id);
224
        }
225

    
226
        ndisk++;
227
    }
228

    
229
    vmtmpl = tpool->get(new_id, true);
230

    
231
    if (vmtmpl == 0)
232
    {
233
        att.resp_msg = "VM template was removed during clone operation.";
234

    
235
        goto error_template;
236
    }
237

    
238
    vmtmpl->replace_disks(vdisks);
239

    
240
    tpool->update(vmtmpl);
241

    
242
    vmtmpl->unlock();
243

    
244
    return SUCCESS;
245

    
246
error_images:
247
    if (tmpl_delete.request_execute(new_id, false, att) != SUCCESS)
248
    {
249
        NebulaLog::log("ReM", Log::ERROR, failure_message(ec, del_att));
250
    }
251

    
252
    goto error_template;
253

    
254
error_template:
255
    for (vector<int>::iterator i = new_ids.begin(); i != new_ids.end(); i++)
256
    {
257
        if (img_delete.request_execute(*i, img_att) != SUCCESS)
258
        {
259
            NebulaLog::log("ReM", Log::ERROR, failure_message(ec, img_att));
260
        }
261
    }
262

    
263
    for (vector<VectorAttribute *>::iterator it = vdisks.begin();
264
            it != vdisks.end() ; it++)
265
    {
266
        delete *it;
267
    }
268

    
269
    return ACTION;
270
}
271

    
272
/* -------------------------------------------------------------------------- */
273
/* -------------------------------------------------------------------------- */
274