3333import java .util .List ;
3434import java .util .Locale ;
3535import java .util .Map ;
36- import java .util .Set ;
36+ import java .util .Objects ;
3737import java .util .UUID ;
3838import java .util .stream .Collectors ;
3939
8484import com .cloud .utils .db .TransactionCallbackNoReturn ;
8585import com .cloud .utils .db .TransactionStatus ;
8686import com .cloud .utils .exception .CloudRuntimeException ;
87+ import com .cloud .utils .net .NetUtils ;
8788import com .cloud .utils .script .Script ;
8889import com .cloud .vm .dao .VMInstanceDao ;
8990import com .cloud .vm .dao .VMInstanceDaoImpl ;
90- import org .apache .cloudstack .engine .subsystem .api .storage .ObjectInDataStoreStateMachine ;
91- import org .apache .cloudstack .framework .config .dao .ConfigurationDao ;
92- import org .apache .cloudstack .framework .config .dao .ConfigurationDaoImpl ;
93- import org .apache .cloudstack .framework .config .impl .ConfigurationVO ;
94- import org .apache .cloudstack .storage .datastore .db .ImageStoreDao ;
95- import org .apache .cloudstack .storage .datastore .db .ImageStoreDaoImpl ;
96- import org .apache .cloudstack .storage .datastore .db .ImageStoreDetailsDao ;
97- import org .apache .cloudstack .storage .datastore .db .ImageStoreDetailsDaoImpl ;
98- import org .apache .cloudstack .storage .datastore .db .ImageStoreVO ;
99- import org .apache .cloudstack .storage .datastore .db .TemplateDataStoreDao ;
100- import org .apache .cloudstack .storage .datastore .db .TemplateDataStoreVO ;
101- import org .apache .cloudstack .utils .security .DigestHelper ;
102- import org .apache .commons .lang3 .StringUtils ;
103- import org .apache .logging .log4j .Logger ;
104- import org .apache .logging .log4j .LogManager ;
105- import org .ini4j .Ini ;
106-
107- import javax .inject .Inject ;
108- import java .io .BufferedReader ;
109- import java .io .File ;
110- import java .io .FileReader ;
111- import java .io .IOException ;
112- import java .net .URI ;
113- import java .nio .file .Files ;
114- import java .nio .file .Path ;
115- import java .nio .file .Paths ;
116- import java .sql .Connection ;
117- import java .sql .Date ;
118- import java .util .ArrayList ;
119- import java .util .Arrays ;
120- import java .util .Collection ;
121- import java .util .Collections ;
122- import java .util .HashMap ;
123- import java .util .HashSet ;
124- import java .util .List ;
125- import java .util .Locale ;
126- import java .util .Map ;
127- import java .util .Objects ;
128- import java .util .Set ;
129- import java .util .UUID ;
130- import java .util .stream .Collectors ;
13191
13292public class SystemVmTemplateRegistration {
13393 protected static Logger LOGGER = LogManager .getLogger (SystemVmTemplateRegistration .class );
134- private static final String MOUNT_COMMAND = "sudo mount -t nfs %s %s " ;
94+ private static final String MOUNT_COMMAND_BASE = "sudo mount -t nfs" ;
13595 private static final String UMOUNT_COMMAND = "sudo umount %s" ;
13696 private static final String RELATIVE_TEMPLATE_PATH = "./engine/schema/dist/systemvm-templates/" ;
13797 private static final String ABSOLUTE_TEMPLATE_PATH = "/usr/share/cloudstack-management/templates/systemvm/" ;
@@ -146,6 +106,9 @@ public class SystemVmTemplateRegistration {
146106 private static final Integer LINUX_7_ID = 183 ;
147107 private static final Integer SCRIPT_TIMEOUT = 1800000 ;
148108 private static final Integer LOCK_WAIT_TIMEOUT = 1200 ;
109+ private static final List <String > DOWNLOADABLE_TEMPLATE_ARCH_TYPES = Arrays .asList (
110+ CPU .archARM64Identifier
111+ );
149112
150113
151114 public static String CS_MAJOR_VERSION = null ;
@@ -193,7 +156,7 @@ public SystemVmTemplateRegistration(String systemVmTemplateVersion) {
193156 }
194157
195158 public static String getMountCommand (String nfsVersion , String device , String dir ) {
196- String cmd = "sudo mount -t nfs" ;
159+ String cmd = MOUNT_COMMAND_BASE ;
197160 if (StringUtils .isNotBlank (nfsVersion )) {
198161 cmd = String .format ("%s -o vers=%s" , cmd , nfsVersion );
199162 }
@@ -789,7 +752,7 @@ public static String parseMetadataFile() {
789752 Ini .Section section = ini .get (key );
790753 NewTemplateMap .put (key , new MetadataTemplateDetails (hypervisorType .first (), section .get ("templatename" ),
791754 section .get ("filename" ), section .get ("downloadurl" ), section .get ("checksum" ),
792- section . get ( "arch" )));
755+ hypervisorType . second ( )));
793756 }
794757 Ini .Section section = ini .get ("default" );
795758 return section .get ("version" );
@@ -809,6 +772,21 @@ private static void cleanupStore(Long templateId, String filePath) {
809772 }
810773 }
811774
775+ protected File getTemplateFile (MetadataTemplateDetails templateDetails ) {
776+ final String filePath = TEMPLATES_PATH + templateDetails .getFilename ();
777+ File tempFile = new File (filePath );
778+ if (!tempFile .exists () && DOWNLOADABLE_TEMPLATE_ARCH_TYPES .contains (templateDetails .getArch ()) &&
779+ StringUtils .isNotBlank (templateDetails .getUrl ())) {
780+ LOGGER .debug ("Downloading the template file {} for hypervisor {} and arch {} as it is not present" ,
781+ templateDetails .getUrl (), templateDetails .getHypervisorType ().name (), templateDetails .getArch ());
782+ if (!NetUtils .downloadFileWithProgress (templateDetails .getUrl (), filePath , LOGGER )) {
783+ return null ;
784+ }
785+ return new File (filePath );
786+ }
787+ return tempFile ;
788+ }
789+
812790 private void validateTemplates (List <Pair <Hypervisor .HypervisorType , String >> hypervisorsArchInUse ) {
813791 boolean templatesFound = true ;
814792 for (Pair <Hypervisor .HypervisorType , String > hypervisorArch : hypervisorsArchInUse ) {
@@ -822,11 +800,12 @@ private void validateTemplates(List<Pair<Hypervisor.HypervisorType, String>> hyp
822800 templatesFound = false ;
823801 break ;
824802 }
825- if (CPU .archARM64Identifier .equals (matchedTemplate .getArch ())) {
826- LOGGER .debug ("Skipping checksum comparison for the template file and metadata as the arch for template is {}" ,
827- matchedTemplate .getArch ());
803+ File tempFile = getTemplateFile (matchedTemplate );
804+ if (tempFile == null ) {
805+ LOGGER .warn ("Failed to download template for hypervisor {} and arch {}, moving ahead" ,
806+ matchedTemplate .getHypervisorType ().name (), matchedTemplate .getArch ());
807+ continue ;
828808 }
829- File tempFile = new File (TEMPLATES_PATH + matchedTemplate .getFilename ());
830809 String templateChecksum = DigestHelper .calculateChecksum (tempFile );
831810 if (!templateChecksum .equals (matchedTemplate .getChecksum ())) {
832811 LOGGER .error ("Checksum {} for file {} does not match checksum {} from metadata" ,
@@ -842,7 +821,7 @@ private void validateTemplates(List<Pair<Hypervisor.HypervisorType, String>> hyp
842821 }
843822 }
844823
845- protected void registerTemplatesForZone (long zoneId ) {
824+ protected void registerTemplatesForZone (long zoneId , String filePath ) {
846825 Pair <String , Long > storeUrlAndId = getNfsStoreInZone (zoneId );
847826 String nfsVersion = getNfsVersion (storeUrlAndId .second ());
848827 mountStore (storeUrlAndId .first (), filePath , nfsVersion );
@@ -856,7 +835,7 @@ protected void registerTemplatesForZone(long zoneId) {
856835 TemplateDataStoreVO templateDataStoreVO = templateDataStoreDao .findByStoreTemplate (storeUrlAndId .second (), templateId );
857836 if (templateDataStoreVO != null ) {
858837 String installPath = templateDataStoreVO .getInstallPath ();
859- if (validateIfSeeded (storeUrlAndId .first (), installPath , nfsVersion )) {
838+ if (validateIfSeeded (templateDataStoreVO , storeUrlAndId .first (), installPath , nfsVersion )) {
860839 continue ;
861840 }
862841 }
@@ -891,7 +870,7 @@ public void doInTransactionWithoutResult(final TransactionStatus status) {
891870 if (filePath == null ) {
892871 throw new CloudRuntimeException ("Failed to create temporary file path to mount the store" );
893872 }
894- registerTemplatesForZone (zoneId );
873+ registerTemplatesForZone (zoneId , filePath );
895874 unmountStore (filePath );
896875 } catch (Exception e ) {
897876 unmountStore (filePath );
0 commit comments