~ubuntu-branches/ubuntu/maverick/eucalyptus/maverick

« back to all changes in this revision

Viewing changes to clc/modules/image-manager/src/main/java/com/eucalyptus/images/ImageUtil.java

  • Committer: Bazaar Package Importer
  • Author(s): Dave Walker (Daviey)
  • Date: 2010-07-21 17:27:10 UTC
  • mfrom: (1.1.38 upstream)
  • Revision ID: james.westby@ubuntu.com-20100721172710-7xv07dmdqgivc3t9
Tags: 2.0~bzr1211-0ubuntu1
* New major upstream version merge, 2.0 (r1211).
* debian/patches/:
  - 01-wsdl-stubs.patch, debian/wsdl.md5sums: wsdl stubs updated.
  - 02-Makefile.patch: Updated to reflect new code layout.
  - 07-local_support_euca_conf-in.patch: Updated to reflect new code layout.
  - 08-ubuntu-default-networking.patch: Refreshed.
  - 09-small-128-192MB.patch: Updated to point to new location.
  - 10-disable-iscsi.patch: Refreshed.
  - 11-state-cleanup-memleakfix.patch: Removed, fixed upstream.
  - 15-fix-default-ramdisk.patch: Updated to point to new location.
  - 16-kvm_libvirt_xml_default_use_kvm.patch: Updated to reflect changes.
  - 17-fix_walrus_OOM_errors.patch: Removed, fixed upstream.
  - 18-priv_security.patch: Updated to reflect upstream changes.
  - 20-brute-force-webui.patch: Updated to reflect upstream changes. 
  - 21-eucalyptus-1.7-with-gwt-1.6.4.patch: New patch, allows 
    eucalyptus-1.7 to be built against gwt 1.6.4. Based on patch courtesy 
    of Dmitrii Zagorodnov, upstream. (LP: #597330)
* debian/eucalyptus-java-common.links: 
  - Changed symlink for groovy, point to groovy.all.jar, making compatiable 
    with groovy versions >1.7. (LP: #595421)
  - Added ant.jar & jetty-rewrite-handler.jar as they are now required.
* debian/control
  - & debian/build-jars: Added libjavassist-java and libjetty-extra-java as 
    build dependencies.
  - Added libjetty-extra-java as a dependency of eucalyptus-java-common
* The binary resulting jar's have been renamed from eucalyptus-*-1.6.2.jar
  to eucalyptus-*-main.jar:    
  - debian/eucalyptus-cc.upstart
  - debian/eucalyptus-cloud.install
  - debian/eucalyptus-common.eucalyptus.upstart
  - debian/eucalyptus-java-common.install
  - debian/eucalyptus-network.upstart
  - debian/eucalyptus-sc.install
  - debian/eucalyptus-walrus.install
* debian/eucalyptus-java-common.install: New upstream jars that have been
  installed:
  - eucalyptus-db-hsqldb-ext-main.jar
  - eucalyptus-component-main.jar
* debian/control:
  - Updated Standards Version to 3.8.4 (no change)
  - Updated the upstream Homepage to: http://open.eucalyptus.com/
  - Changed Vcs-Bzr to reflect new location of Ubuntu hosted development branch.
  - Made the Build Dependency of groovy and the binary eucalyptus-java-common
    package depend on version >=1.7.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*******************************************************************************
 
2
 *Copyright (c) 2009  Eucalyptus Systems, Inc.
 
3
 * 
 
4
 *  This program is free software: you can redistribute it and/or modify
 
5
 *  it under the terms of the GNU General Public License as published by
 
6
 *  the Free Software Foundation, only version 3 of the License.
 
7
 * 
 
8
 * 
 
9
 *  This file is distributed in the hope that it will be useful, but WITHOUT
 
10
 *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 
11
 *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 
12
 *  for more details.
 
13
 * 
 
14
 *  You should have received a copy of the GNU General Public License along
 
15
 *  with this program.  If not, see <http://www.gnu.org/licenses/>.
 
16
 * 
 
17
 *  Please contact Eucalyptus Systems, Inc., 130 Castilian
 
18
 *  Dr., Goleta, CA 93101 USA or visit <http://www.eucalyptus.com/licenses/>
 
19
 *  if you need additional information or have any questions.
 
20
 * 
 
21
 *  This file may incorporate work covered under the following copyright and
 
22
 *  permission notice:
 
23
 * 
 
24
 *    Software License Agreement (BSD License)
 
25
 * 
 
26
 *    Copyright (c) 2008, Regents of the University of California
 
27
 *    All rights reserved.
 
28
 * 
 
29
 *    Redistribution and use of this software in source and binary forms, with
 
30
 *    or without modification, are permitted provided that the following
 
31
 *    conditions are met:
 
32
 * 
 
33
 *      Redistributions of source code must retain the above copyright notice,
 
34
 *      this list of conditions and the following disclaimer.
 
35
 * 
 
36
 *      Redistributions in binary form must reproduce the above copyright
 
37
 *      notice, this list of conditions and the following disclaimer in the
 
38
 *      documentation and/or other materials provided with the distribution.
 
39
 * 
 
40
 *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 
41
 *    IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 
42
 *    TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 
43
 *    PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
 
44
 *    OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 
45
 *    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 
46
 *    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 
47
 *    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 
48
 *    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 
49
 *    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 
50
 *    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. USERS OF
 
51
 *    THIS SOFTWARE ACKNOWLEDGE THE POSSIBLE PRESENCE OF OTHER OPEN SOURCE
 
52
 *    LICENSED MATERIAL, COPYRIGHTED MATERIAL OR PATENTED MATERIAL IN THIS
 
53
 *    SOFTWARE, AND IF ANY SUCH MATERIAL IS DISCOVERED THE PARTY DISCOVERING
 
54
 *    IT MAY INFORM DR. RICH WOLSKI AT THE UNIVERSITY OF CALIFORNIA, SANTA
 
55
 *    BARBARA WHO WILL THEN ASCERTAIN THE MOST APPROPRIATE REMEDY, WHICH IN
 
56
 *    THE REGENTS’ DISCRETION MAY INCLUDE, WITHOUT LIMITATION, REPLACEMENT
 
57
 *    OF THE CODE SO IDENTIFIED, LICENSING OF THE CODE SO IDENTIFIED, OR
 
58
 *    WITHDRAWAL OF THE CODE CAPABILITY TO THE EXTENT NEEDED TO COMPLY WITH
 
59
 *    ANY SUCH LICENSES OR RIGHTS.
 
60
 *******************************************************************************/
 
61
/*
 
62
 * Author: chris grzegorczyk <grze@eucalyptus.com>
 
63
 */
 
64
package com.eucalyptus.images;
 
65
 
 
66
import java.net.MalformedURLException;
 
67
import java.net.URL;
 
68
import java.security.PublicKey;
 
69
import java.security.Signature;
 
70
import java.security.cert.X509Certificate;
 
71
import java.util.ArrayList;
 
72
import java.util.List;
 
73
import java.util.zip.Adler32;
 
74
import javax.xml.xpath.XPath;
 
75
import javax.xml.xpath.XPathConstants;
 
76
import javax.xml.xpath.XPathExpressionException;
 
77
import javax.xml.xpath.XPathFactory;
 
78
import org.apache.log4j.Logger;
 
79
import org.w3c.dom.DOMException;
 
80
import org.w3c.dom.Document;
 
81
import org.w3c.dom.NodeList;
 
82
import com.eucalyptus.auth.Groups;
 
83
import com.eucalyptus.auth.NoSuchGroupException;
 
84
import com.eucalyptus.auth.NoSuchUserException;
 
85
import com.eucalyptus.auth.GroupEntity;
 
86
import com.eucalyptus.auth.UserInfo;
 
87
import com.eucalyptus.auth.UserInfoStore;
 
88
import com.eucalyptus.auth.Users;
 
89
import com.eucalyptus.auth.util.Hashes;
 
90
import com.eucalyptus.blockstorage.WalrusUtil;
 
91
import com.eucalyptus.bootstrap.Component;
 
92
import com.eucalyptus.entities.EntityWrapper;
 
93
import com.eucalyptus.images.Image;
 
94
import com.eucalyptus.images.ImageInfo;
 
95
import com.eucalyptus.util.EucalyptusCloudException;
 
96
import com.google.common.base.Predicate;
 
97
import com.google.common.collect.Iterables;
 
98
import com.google.common.collect.Lists;
 
99
import edu.ucsb.eucalyptus.cloud.VmImageInfo;
 
100
import edu.ucsb.eucalyptus.cloud.VmInfo;
 
101
import edu.ucsb.eucalyptus.cloud.entities.SystemConfiguration;
 
102
import edu.ucsb.eucalyptus.msgs.BlockDeviceMappingItemType;
 
103
import edu.ucsb.eucalyptus.msgs.GetBucketAccessControlPolicyResponseType;
 
104
import edu.ucsb.eucalyptus.msgs.ImageDetails;
 
105
import edu.ucsb.eucalyptus.msgs.LaunchPermissionItemType;
 
106
import edu.ucsb.eucalyptus.msgs.RegisterImageType;
 
107
 
 
108
public class ImageUtil {
 
109
  private static Logger LOG = Logger.getLogger( ImageUtil.class );
 
110
  
 
111
  public static String generateImageId( final String imagePrefix, final String imageLocation ) {
 
112
    Adler32 hash = new Adler32( );
 
113
    String key = imageLocation + System.currentTimeMillis( );
 
114
    hash.update( key.getBytes( ) );
 
115
    String imageId = String.format( "%s-%08X", imagePrefix, hash.getValue( ) );
 
116
    return imageId;
 
117
  }
 
118
  public static String newImageId( final String imagePrefix, final String imageLocation ) {
 
119
    EntityWrapper<Image> db = new EntityWrapper<Image>( );
 
120
    Image query = new ImageInfo( );
 
121
    query.setImageId( generateImageId( imagePrefix, imageLocation ) );
 
122
    LOG.info( "Trying to lookup using created AMI id=" + query.getImageId( ) );
 
123
    for ( ; db.query( query ).size( ) != 0; query.setImageId( generateImageId( imagePrefix, imageLocation ) ) );
 
124
    db.commit( );
 
125
    LOG.info( "Assigning imageId=" + query.getImageId( ) );
 
126
    return query.getImageId( );
 
127
  }
 
128
  public static boolean verifyManifestSignature( final String signature, final X509Certificate cert, String pad ) {
 
129
    boolean ret = false;
 
130
    try {
 
131
      Signature sigVerifier = Signature.getInstance( "SHA1withRSA" );
 
132
      if ( cert != null ) {
 
133
        PublicKey publicKey = cert.getPublicKey( );
 
134
        sigVerifier.initVerify( publicKey );
 
135
        sigVerifier.update( pad.getBytes( ) );
 
136
        ret = sigVerifier.verify( Hashes.hexToBytes( signature ) );
 
137
      }
 
138
    } catch ( Exception ex ) {
 
139
      LOG.warn( ex.getMessage( ) );
 
140
    }
 
141
 // TODO: RELEASE: restore
 
142
//    return ret;
 
143
    return true;
 
144
  }
 
145
  public static ArrayList<String> getAncestors( String userId, String manifestPath ) {
 
146
    ArrayList<String> ancestorIds = Lists.newArrayList( );
 
147
    try {
 
148
      String[] imagePathParts = manifestPath.split( "/" );
 
149
      Document inputSource = WalrusUtil.getManifestData( Component.eucalyptus.name( ), imagePathParts[0], imagePathParts[1] );
 
150
      XPath xpath = XPathFactory.newInstance( ).newXPath( );
 
151
      NodeList ancestors = null;
 
152
      try {
 
153
        ancestors = ( NodeList ) xpath.evaluate( "/manifest/image/ancestry/ancestor_ami_id/text()", inputSource, XPathConstants.NODESET );
 
154
        if ( ancestors == null ) return ancestorIds;
 
155
        for ( int i = 0; i < ancestors.getLength( ); i++ ) {
 
156
          for ( String ancestorId : ancestors.item( i ).getNodeValue( ).split( "," ) ) {
 
157
            ancestorIds.add( ancestorId );
 
158
          }
 
159
        }
 
160
      } catch ( XPathExpressionException e ) {
 
161
        ImageManager.LOG.error( e, e );
 
162
      }
 
163
    } catch ( EucalyptusCloudException e ) {
 
164
      ImageManager.LOG.error( e, e );
 
165
    } catch ( DOMException e ) {
 
166
      ImageManager.LOG.error( e, e );
 
167
    }
 
168
    return ancestorIds;
 
169
  }
 
170
  public static Long getSize( String userId, String manifestPath ) {
 
171
    Long size = 0l;
 
172
    try {
 
173
      String[] imagePathParts = manifestPath.split( "/" );
 
174
      Document inputSource = WalrusUtil.getManifestData( Component.eucalyptus.name( ), imagePathParts[0], imagePathParts[1] );
 
175
      XPath xpath = XPathFactory.newInstance( ).newXPath( );
 
176
      String rootSize = "0";
 
177
      try {
 
178
        rootSize = ( String ) xpath.evaluate( "/manifest/image/size/text()", inputSource, XPathConstants.STRING );
 
179
        try {
 
180
          size = Long.parseLong( rootSize );
 
181
        } catch ( NumberFormatException e ) {
 
182
          ImageManager.LOG.error( e, e );
 
183
        }
 
184
      } catch ( XPathExpressionException e ) {
 
185
        ImageManager.LOG.error( e, e );
 
186
      }
 
187
    } catch ( EucalyptusCloudException e ) {
 
188
      ImageManager.LOG.error( e, e );
 
189
    }
 
190
    return size;
 
191
  }
 
192
  public static void checkStoredImage( final ImageInfo imgInfo ) throws EucalyptusCloudException {
 
193
    if ( imgInfo != null ) try {
 
194
      Document inputSource = null;
 
195
      try {
 
196
        String[] imagePathParts = imgInfo.getImageLocation( ).split( "/" );
 
197
        inputSource = WalrusUtil.getManifestData( imgInfo.getImageOwnerId( ), imagePathParts[0], imagePathParts[1] );
 
198
      } catch ( EucalyptusCloudException e ) {
 
199
        throw e;
 
200
      }
 
201
      XPath xpath = null;
 
202
      xpath = XPathFactory.newInstance( ).newXPath( );
 
203
      String signature = null;
 
204
      try {
 
205
        signature = ( String ) xpath.evaluate( "/manifest/signature/text()", inputSource, XPathConstants.STRING );
 
206
      } catch ( XPathExpressionException e ) {}
 
207
      if ( imgInfo.getSignature( ) != null && !imgInfo.getSignature( ).equals( signature ) ) throw new EucalyptusCloudException(
 
208
        "Manifest signature has changed since registration." );
 
209
      ImageManager.LOG.info( "Checking image: " + imgInfo.getImageLocation( ) );
 
210
      WalrusUtil.checkValid( imgInfo );
 
211
      ImageManager.LOG.info( "Triggering caching: " + imgInfo.getImageLocation( ) );
 
212
      try {
 
213
        WalrusUtil.triggerCaching( imgInfo );
 
214
      } catch ( Exception e ) {}
 
215
    } catch ( EucalyptusCloudException e ) {
 
216
      ImageManager.LOG.error( e );
 
217
      ImageManager.LOG.error( "Failed bukkit check! Invalidating registration: " + imgInfo.getImageLocation( ) );
 
218
      //TODO: we need to consider if this is a good semantic or not, it can have ugly side effects
 
219
      //        invalidateImageById( imgInfo.getImageId() );
 
220
      throw new EucalyptusCloudException( "Failed check! Invalidating registration: " + imgInfo.getImageLocation( ) );
 
221
    }
 
222
  }
 
223
  public static String getImageUrl( String walrusUrl, final Image diskInfo ) throws EucalyptusCloudException {
 
224
    try {
 
225
      URL url = new URL( ImageUtil.getWalrusUrl( ) + diskInfo.getImageLocation( ) );
 
226
      return url.toString( );
 
227
    } catch ( MalformedURLException e ) {
 
228
      throw new EucalyptusCloudException( "Failed to parse image location as URL.", e );
 
229
    }
 
230
  }
 
231
  public static String getWalrusUrl( ) throws EucalyptusCloudException {
 
232
    try {
 
233
      return SystemConfiguration.getWalrusUrl( ) + "/";
 
234
    } catch ( Exception e ) {
 
235
      LOG.debug( e, e );
 
236
      throw new EucalyptusCloudException( "Walrus has not been configured.", e );
 
237
    }
 
238
  }
 
239
  public static boolean isSet( String id ) {
 
240
    return id != null && !"".equals( id );
 
241
  }
 
242
  private static boolean userHasImagePermission( final UserInfo user, final ImageInfo img ) {
 
243
    try {
 
244
      if ( /*img.getUserGroups( ).isEmpty( ) && */!user.getUserName( ).equals( img.getImageOwnerId( ) )
 
245
           && !Users.lookupUser( user.getUserName( ) ).isAdministrator( ) && !img.getPermissions( ).contains( user ) ) return true;
 
246
    } catch ( NoSuchUserException e ) {
 
247
      return false;
 
248
    }
 
249
    return false;
 
250
  }
 
251
  private static void invalidateImageById( String searchId ) throws EucalyptusCloudException {
 
252
    EntityWrapper<ImageInfo> db = new EntityWrapper<ImageInfo>( );
 
253
    if ( isSet( searchId ) ) try {
 
254
      Image img = db.getUnique( new ImageInfo( searchId ) );
 
255
      WalrusUtil.invalidate( img );
 
256
      db.commit( );
 
257
    } catch ( EucalyptusCloudException e ) {
 
258
      db.rollback( );
 
259
      throw new EucalyptusCloudException( "Failed to find registered image with id " + searchId );
 
260
    }
 
261
  }
 
262
  public static VmImageInfo getVmImageInfo( final String walrusUrl, final Image diskInfo, final Image kernelInfo, final Image ramdiskInfo, final ArrayList<String> productCodes ) throws EucalyptusCloudException {
 
263
    String diskUrl = getImageUrl( walrusUrl, diskInfo );
 
264
    String kernelUrl = kernelInfo != null ? getImageUrl( walrusUrl, kernelInfo ) : null;
 
265
    String ramdiskUrl = ramdiskInfo != null ? getImageUrl( walrusUrl, ramdiskInfo ) : null;
 
266
    //:: create the response assets now since we might not have a ramdisk anyway :://
 
267
    VmImageInfo vmImgInfo = new VmImageInfo( diskInfo.getImageId( ), kernelInfo == null ? null : kernelInfo.getImageId( ),
 
268
      ramdiskInfo == null ? null : ramdiskInfo.getImageId( ), diskUrl, kernelUrl, ramdiskInfo == null ? null
 
269
                                                                                                     : ramdiskUrl,
 
270
      productCodes );
 
271
    return vmImgInfo;
 
272
  }
 
273
  public static Image getImageInfobyId( String searchId ) throws EucalyptusCloudException {
 
274
    EntityWrapper<ImageInfo> db = new EntityWrapper<ImageInfo>( );
 
275
    if ( isSet( searchId ) ) try {
 
276
      Image imgInfo = db.getUnique( new ImageInfo( searchId ) );
 
277
      db.commit( );
 
278
      return imgInfo;
 
279
    } catch ( EucalyptusCloudException e ) {
 
280
      LOG.error( e, e );
 
281
      db.commit( );
 
282
      throw new EucalyptusCloudException( "Failed to find registered image with id " + searchId );
 
283
    } catch ( Throwable t ) {
 
284
      LOG.error( t, t );
 
285
      db.commit( );
 
286
    }
 
287
    LOG.error( "Failed to find registered image with id " + searchId );
 
288
    throw new EucalyptusCloudException( "Failed to find registered image with id " + searchId );
 
289
  }
 
290
  public static String getImageInfobyId( String userSuppliedId, String imageDefaultId, String systemDefaultId ) {
 
291
    String searchId = null;
 
292
    if ( isSet( userSuppliedId ) )
 
293
      searchId = userSuppliedId;
 
294
    else if ( isSet( imageDefaultId ) )
 
295
      searchId = imageDefaultId;
 
296
    else if ( isSet( systemDefaultId ) ) searchId = systemDefaultId;
 
297
    return searchId;
 
298
  }
 
299
  
 
300
  public static BlockDeviceMappingItemType EMI       = new BlockDeviceMappingItemType( "emi", "sda1" );
 
301
  public static BlockDeviceMappingItemType EPHEMERAL = new BlockDeviceMappingItemType( "ephemeral0", "sda2" );
 
302
  public static BlockDeviceMappingItemType SWAP      = new BlockDeviceMappingItemType( "swap", "sda3" );
 
303
  public static BlockDeviceMappingItemType ROOT      = new BlockDeviceMappingItemType( "root", "/dev/sda1" );
 
304
  
 
305
  public static String extractArchitecture( Document inputSource, XPath xpath ) {
 
306
    String arch = null;
 
307
    try {
 
308
      arch = ( String ) xpath.evaluate( "/manifest/machine_configuration/architecture/text()", inputSource, XPathConstants.STRING );
 
309
    } catch ( XPathExpressionException e ) {
 
310
      ImageManager.LOG.warn( e.getMessage( ) );
 
311
    }
 
312
    return arch;
 
313
  }
 
314
  public static String extractRamdiskId( Document inputSource, XPath xpath ) {
 
315
    String ramdiskId = null;
 
316
    try {
 
317
      ramdiskId = ( String ) xpath.evaluate( "/manifest/machine_configuration/ramdisk_id/text()", inputSource, XPathConstants.STRING );
 
318
    } catch ( XPathExpressionException e ) {
 
319
      ImageManager.LOG.warn( e.getMessage( ) );
 
320
    }
 
321
    if ( !isSet( ramdiskId ) ) ramdiskId = null;
 
322
    return ramdiskId;
 
323
  }
 
324
  public static String extractKernelId( Document inputSource, XPath xpath ) {
 
325
    String kernelId = null;
 
326
    try {
 
327
      kernelId = ( String ) xpath.evaluate( "/manifest/machine_configuration/kernel_id/text()", inputSource, XPathConstants.STRING );
 
328
    } catch ( XPathExpressionException e ) {
 
329
      ImageManager.LOG.warn( e.getMessage( ) );
 
330
    }
 
331
    if ( !isSet( kernelId ) ) kernelId = null;
 
332
    return kernelId;
 
333
  }
 
334
  public static String[] getImagePathParts( String imageLocation ) throws EucalyptusCloudException {
 
335
    String[] imagePathParts = imageLocation.split( "/" );
 
336
    if ( imagePathParts.length != 2 ) throw new EucalyptusCloudException(
 
337
      "Image registration failed:  Invalid image location." );
 
338
    return imagePathParts;
 
339
  }
 
340
  public static void checkBucketAcl( RegisterImageType request, String[] imagePathParts ) throws EucalyptusCloudException {
 
341
    String userName = null;
 
342
    if ( !request.isAdministrator( ) ) {
 
343
      GetBucketAccessControlPolicyResponseType reply = WalrusUtil.getBucketAcl( request, imagePathParts );
 
344
      if ( reply != null ) {
 
345
        if ( !request.getUserId( ).equals( reply.getAccessControlPolicy( ).getOwner( ).getDisplayName( ) ) ) throw new EucalyptusCloudException(
 
346
          "Image registration failed: you must own the bucket containing the image." );
 
347
        userName = reply.getAccessControlPolicy( ).getOwner( ).getDisplayName( );
 
348
      }
 
349
    }
 
350
  }
 
351
  public static void applyImageAttributes( final EntityWrapper<ImageInfo> db, final ImageInfo imgInfo, final List<LaunchPermissionItemType> changeList, final boolean adding ) throws EucalyptusCloudException {
 
352
    for ( LaunchPermissionItemType perm : changeList ) {
 
353
      if ( perm.isGroup( ) ) {
 
354
        try {
 
355
          if( adding ) {
 
356
            imgInfo.grantPermission( Groups.lookupGroup( perm.getGroup( ) ) );
 
357
          } else {
 
358
            imgInfo.revokePermission( Groups.lookupGroup( perm.getGroup( ) ) );
 
359
          }
 
360
        } catch ( NoSuchGroupException e ) {
 
361
          LOG.debug( e, e );
 
362
          throw new EucalyptusCloudException( "Modify image attribute failed because of: " + e.getMessage( ) );
 
363
        }
 
364
      } else if ( perm.isUser( ) ) {
 
365
        try {
 
366
          if( adding ) {
 
367
            imgInfo.grantPermission( Users.lookupUser( perm.getUserId( ) ) );
 
368
          } else {
 
369
            imgInfo.revokePermission( Users.lookupUser( perm.getUserId( ) ) );
 
370
          }
 
371
        } catch ( NoSuchUserException e ) {
 
372
          LOG.debug( e, e );
 
373
          throw new EucalyptusCloudException( "Modify image attribute failed because of: " + e.getMessage( ) );
 
374
        }
 
375
      }
 
376
    }
 
377
  }
 
378
  public static boolean modifyImageInfo( final String imageId, final String userId, final boolean isAdmin, final List<LaunchPermissionItemType> addList, final List<LaunchPermissionItemType> remList ) {
 
379
    EntityWrapper<ImageInfo> db = new EntityWrapper<ImageInfo>( );
 
380
    ImageInfo imgInfo = null;
 
381
    try {
 
382
      imgInfo = db.getUnique( new ImageInfo( imageId ) );
 
383
    } catch ( EucalyptusCloudException e ) {
 
384
      db.rollback( );
 
385
      return false;
 
386
    }
 
387
    if ( !userId.equals( imgInfo.getImageOwnerId( ) ) && !isAdmin ) return false;
 
388
    try {
 
389
      applyImageAttributes( db, imgInfo, addList, true );
 
390
      applyImageAttributes( db, imgInfo, remList, false );
 
391
      db.commit( );
 
392
      return true;
 
393
    } catch ( EucalyptusCloudException e ) {
 
394
      ImageManager.LOG.warn( e );
 
395
      db.rollback( );
 
396
      return false;
 
397
    }
 
398
  }
 
399
  public static Document getManifestDocument( String[] imagePathParts, String userName ) throws EucalyptusCloudException {
 
400
    Document inputSource = null;
 
401
    try {
 
402
      inputSource = WalrusUtil.getManifestData( userName, imagePathParts[0], imagePathParts[1] );
 
403
    } catch ( EucalyptusCloudException e ) {
 
404
      throw e;
 
405
    }
 
406
    return inputSource;
 
407
  }
 
408
  public static List<ImageDetails> getImageOwnedByUser( List<ImageInfo> imgList, UserInfo user ) {
 
409
    EntityWrapper<ImageInfo> db = new EntityWrapper<ImageInfo>( );
 
410
    List<ImageDetails> repList = Lists.newArrayList( );
 
411
    try {
 
412
      List<ImageInfo> results = db.query( new ImageInfo( ) );
 
413
      for ( ImageInfo img : results ) {
 
414
        ImageDetails imgDetails = img.getAsImageDetails( );
 
415
        if ( img.isAllowed( user ) && ( imgList.isEmpty( ) || imgList.contains( img ) ) ) {
 
416
          repList.add( imgDetails );
 
417
        }
 
418
      }
 
419
      db.commit( );
 
420
    } catch ( Throwable e ) {
 
421
      db.commit( );
 
422
      ImageManager.LOG.debug( e, e );
 
423
    }
 
424
    return repList;
 
425
  }
 
426
  public static List<ImageDetails> getImagesByOwner( final List<ImageInfo> imgList, final UserInfo user, final ArrayList<String> owners ) {
 
427
    EntityWrapper<ImageInfo> db = new EntityWrapper<ImageInfo>( );
 
428
    List<ImageDetails> repList = Lists.newArrayList( );
 
429
    if ( owners.remove( "self" ) ) owners.add( user.getUserName( ) );
 
430
    try {
 
431
      for ( String userName : owners ) {
 
432
        Iterable<ImageInfo> results = Iterables.filter( db.query( ImageInfo.byOwnerId( userName ) ), new Predicate<ImageInfo>( ) {
 
433
          @Override public boolean apply( ImageInfo arg0 ) {
 
434
            return ( imgList.isEmpty( ) || imgList.contains( arg0 ) )
 
435
                   && ( arg0.getImagePublic( ) || arg0.isAllowed( user ) );
 
436
          }
 
437
        } );
 
438
        repList.addAll( Lists.transform( Lists.newArrayList( results ), ImageInfo.TO_IMAGE_DETAILS ) );
 
439
      }
 
440
      db.commit( );
 
441
    } catch ( Throwable e ) {
 
442
      LOG.debug( e, e );
 
443
      db.rollback( );
 
444
    }
 
445
    return repList;
 
446
  }
 
447
  public static List<ImageDetails> getImagesByExec( UserInfo user, ArrayList<String> executable ) {
 
448
    List<ImageDetails> repList = Lists.newArrayList( );
 
449
    EntityWrapper<ImageInfo> db = new EntityWrapper<ImageInfo>( );
 
450
    try {
 
451
      for ( String execUserId : executable ) {
 
452
        if ( "all".equals( execUserId ) ) continue;
 
453
        final UserInfo execUser = UserInfoStore.getUserInfo( new UserInfo( execUserId ) );
 
454
        Iterable<ImageInfo> results = Iterables.filter( db.query( ImageInfo.ALL ), new Predicate<ImageInfo>( ) {
 
455
          @Override public boolean apply( ImageInfo arg0 ) {
 
456
            return arg0.isAllowed( execUser ) || arg0.getImagePublic( );
 
457
          }
 
458
        } );
 
459
        repList.addAll( Lists.transform( Lists.newArrayList( results ), ImageInfo.TO_IMAGE_DETAILS ) );
 
460
      }
 
461
      db.commit( );
 
462
    } catch ( NoSuchUserException e ) {
 
463
      LOG.debug( e, e );
 
464
      db.commit( );
 
465
    }
 
466
    return repList;
 
467
  }
 
468
  public static void cleanDeregistered( ) {
 
469
    EntityWrapper<ImageInfo> db = new EntityWrapper<ImageInfo>( );
 
470
    try {
 
471
      List<ImageInfo> imgList = db.query( ImageInfo.deregistered( ) );
 
472
      for ( ImageInfo deregImg : imgList ) {
 
473
        try {
 
474
          db.delete( deregImg );
 
475
        } catch ( Throwable e1 ) {}
 
476
      }
 
477
      db.commit( );
 
478
    } catch ( Throwable e1 ) {
 
479
      db.rollback( );
 
480
    }
 
481
  }
 
482
  public static VmImageInfo resolveImage( VmInfo vmInfo ) throws EucalyptusCloudException {
 
483
    String walrusUrl = getWalrusUrl( );
 
484
    ArrayList<String> productCodes = Lists.newArrayList( );
 
485
    ImageInfo diskInfo = null, kernelInfo = null, ramdiskInfo = null;
 
486
    String diskUrl = null, kernelUrl = null, ramdiskUrl = null;
 
487
  
 
488
    EntityWrapper<ImageInfo> db = new EntityWrapper<ImageInfo>( );
 
489
    try {
 
490
      diskInfo = db.getUnique( new ImageInfo( vmInfo.getImageId( ) ) );
 
491
      for ( ProductCode p : diskInfo.getProductCodes( ) ) {
 
492
        productCodes.add( p.getValue( ) );
 
493
      }
 
494
      diskUrl = getImageUrl( walrusUrl, diskInfo );
 
495
      db.commit( );
 
496
    } catch ( EucalyptusCloudException e ) {
 
497
      db.rollback( );
 
498
    }
 
499
    VmImageInfo vmImgInfo = new VmImageInfo( vmInfo.getImageId( ), vmInfo.getKernelId( ), vmInfo.getRamdiskId( ), diskUrl, null, null, productCodes );
 
500
    if( Component.walrus.isLocal( ) ) {
 
501
      ArrayList<String> ancestorIds = getAncestors( vmInfo.getOwnerId( ), diskInfo.getImageLocation( ) );
 
502
      vmImgInfo.setAncestorIds( ancestorIds );
 
503
    } else {//FIXME: handle populating these in a defered way for the remote case.
 
504
      vmImgInfo.setAncestorIds( new ArrayList<String>() );
 
505
    }
 
506
    return vmImgInfo;
 
507
  }
 
508
}