1
package com.eucalyptus.bootstrap;
4
import java.util.Arrays;
6
import org.apache.log4j.Logger;
7
import com.eucalyptus.bootstrap.transitions.LoadConfigs;
8
import com.eucalyptus.component.Component;
9
import com.eucalyptus.component.Components;
10
import com.eucalyptus.component.Lifecycles;
11
import com.eucalyptus.component.Resource;
12
import com.eucalyptus.records.EventRecord;
13
import com.eucalyptus.records.EventType;
14
import com.eucalyptus.system.Ats;
15
import com.eucalyptus.system.BaseDirectory;
16
import com.eucalyptus.util.Committor;
17
import com.eucalyptus.util.LogUtil;
18
import com.eucalyptus.util.Transition;
19
import com.google.common.collect.Lists;
21
public class Bootstrap {
22
private static Logger LOG = Logger.getLogger( Bootstrap.class );
26
PrivilegedConfiguration,
27
UnprivilegedConfiguration,
28
SystemCredentialsInit, /* <-- this means system credentials, not user. */
31
PersistenceContextInit,
39
public static List<Stage> list( ) {
40
return Arrays.asList( Stage.values( ) );
43
public <A> Transition<A, Bootstrap.Stage> to( final Bootstrap.Stage s, final Committor<A> c ) throws Exception {
44
return ( Transition<A, Bootstrap.Stage> ) Transition.anonymous( this, s, c );
47
private List<Bootstrapper> bootstrappers = Lists.newArrayList( );
48
private List<Resource> resources = Lists.newArrayList( );
50
public <A, B extends Comparable<? extends Comparable<?>>> Transition<A,Comparable<? extends Comparable<?>>> to( B s, Committor<A> c ) throws Exception {
51
return ( Transition<A,Comparable<? extends Comparable<?>>> ) Transition.anonymous( this, s, c );
54
public List<Bootstrapper> getBootstrappers( ) {
55
return this.bootstrappers;
58
public void addBootstrapper( Bootstrapper b ) {
59
if ( this.bootstrappers.contains( b ) ) {
60
throw BootstrapException.throwFatal( "Duplicate bootstrapper registration: " + b.getClass( ).toString( ) );
62
this.bootstrappers.add( b );
66
public void printAgenda( ) {
67
EventRecord.here( Bootstrap.class, EventType.BOOTSTRAP_STAGE_AGENDA, this.name( ), Bootstrap.loading ? "LOAD" : "START" ).info( );
68
for ( Bootstrapper b : this.bootstrappers ) {
69
EventRecord.here( Bootstrap.class, EventType.BOOTSTRAP_STAGE_AGENDA, this.name( ), b.getClass( ).getCanonicalName( ) ).info( );
73
public void updateBootstrapDependencies( ) {
74
for ( Bootstrapper b : Lists.newArrayList( this.bootstrappers ) ) {
75
if ( !b.checkLocal( ) ) {
76
EventRecord.here( Bootstrap.class, EventType.BOOTSTRAPPER_SKIPPED, "stage:" + Bootstrap.getCurrentStage( ), this.getClass( ).getSimpleName( ),
77
"Depends.local=" + b.toString( ), "Component." + b.toString( ) + "=remote" ).info( );
78
this.bootstrappers.remove( b );
79
} else if ( !b.checkRemote( ) ) {
80
EventRecord.here( Bootstrap.class, EventType.BOOTSTRAPPER_SKIPPED, "stage:" + Bootstrap.getCurrentStage( ), this.getClass( ).getSimpleName( ),
81
"Depends.remote=" + b.toString( ), "Component." + b.toString( ) + "=local" ).info( );
82
this.bootstrappers.remove( b );
88
this.updateBootstrapDependencies( );
90
for ( Bootstrapper b : this.bootstrappers ) {
92
EventRecord.here( Bootstrap.class, EventType.BOOTSTRAPPER_LOAD, this.name( ), b.getClass( ).getCanonicalName( ) ).info( );
93
boolean result = b.load( this );
95
throw BootstrapException.throwFatal( b.getClass( ).getSimpleName( ) + " returned 'false' from load( ): terminating bootstrap." );
97
} catch ( Throwable e ) {
98
EventRecord.here( Bootstrap.class, EventType.BOOTSTRAPPER_ERROR, this.name( ), b.getClass( ).getCanonicalName( ) ).info( );
99
throw BootstrapException.throwFatal( b.getClass( ).getSimpleName( ) + " threw an error in load( ): " + e.getMessage( ), e );
104
public void start( ) {
105
this.updateBootstrapDependencies( );
107
for ( Bootstrapper b : this.bootstrappers ) {
109
EventRecord.here( Bootstrap.class, EventType.BOOTSTRAPPER_START, this.name( ), b.getClass( ).getCanonicalName( ) ).info( );
110
boolean result = b.start( );
112
throw BootstrapException.throwFatal( b.getClass( ).getSimpleName( ) + " returned 'false' from start( ): terminating bootstrap." );
114
} catch ( Throwable e ) {
115
EventRecord.here( Bootstrap.class, EventType.BOOTSTRAPPER_ERROR, this.name( ), b.getClass( ).getCanonicalName( ) ).info( );
116
throw BootstrapException.throwFatal( b.getClass( ).getSimpleName( ) + " threw an error in start( ): " + e.getMessage( ), e );
121
public String describe( ) {
122
StringBuffer buf = new StringBuffer( );
123
for ( Bootstrapper b : this.bootstrappers ) {
124
buf.append( EventRecord.caller( Component.class, EventType.COMPONENT_INFO, this.name( ), b.getClass( ).getSimpleName( ) ) ).append( "\n" );
126
return buf.toString( );
129
public String getResourceName( ) {
130
return String.format( "com.eucalyptus.%sProvider", this.name( ).replaceAll( "Init\\Z", "" ) );
133
public List<Resource> getResources( ) {
134
return this.resources;
139
private static Boolean loading = false;
140
private static Boolean starting = false;
141
private static Boolean finished = false;
142
private static Stage currentStage = Stage.SystemInit;
144
public static Stage getCurrentStage( ) {
148
private static void doDiscovery( ) {
149
File libDir = new File( BaseDirectory.LIB.toString( ) );
150
for ( File f : libDir.listFiles( ) ) {
151
if ( f.getName( ).startsWith( com.eucalyptus.bootstrap.Component.eucalyptus.name( ) ) && f.getName( ).endsWith( ".jar" )
152
&& !f.getName( ).matches( ".*-ext-.*" ) ) {
153
LOG.debug( "Found eucalyptus component jar: " + f.getName( ) );
155
ServiceJarDiscovery.processFile( f );
156
} catch ( Throwable e ) {
157
LOG.error( e.getMessage( ) );
162
ServiceJarDiscovery.runDiscovery( );
165
@SuppressWarnings( "deprecation" )
166
public static void initBootstrappers( ) {
167
for ( Bootstrapper bootstrap : BootstrapperDiscovery.getBootstrappers( ) ) {//these have all been checked at discovery time
168
com.eucalyptus.bootstrap.Component comp, old = com.eucalyptus.bootstrap.Component.any;
169
String bc = bootstrap.getClass( ).getCanonicalName( );
170
Bootstrap.Stage stage = Ats.from( bootstrap ).get( RunDuring.class ).value( );
171
Provides p = Ats.from( bootstrap ).get( Provides.class );
172
comp = ( p.value( ) == null ? old : p.value( ) );//TODO: remap orphan bootstrapper to 'any'
173
if ( Components.delegate.any.equals( comp ) ) {
174
EventRecord.here( Bootstrap.class, EventType.BOOTSTRAPPER_ADDED, currentStage.name( ), bc, "Provides", comp.name( ),
175
"Component." + comp.name( ) + ".isEnabled", "true" ).info( );
176
stage.addBootstrapper( bootstrap );
177
} else if ( !comp.isSingleton( ) && !comp.isEnabled( ) && Components.contains( comp ) ) { //report skipping a bootstrapper for an enabled component
178
EventRecord.here( Bootstrap.class, EventType.BOOTSTRAPPER_SKIPPED, currentStage.name( ), bc, "Provides", comp.name( ),
179
"Component." + comp.name( ) + ".isEnabled", comp.isEnabled( ).toString( ) ).info( );
180
} else if ( !bootstrap.checkLocal( ) ) {
181
EventRecord.here( Bootstrap.class, EventType.BOOTSTRAPPER_SKIPPED, currentStage.name( ), bc, "DependsLocal", comp.name( ),
182
"Component." + comp.name( ) + ".isLocal", comp.isLocal( ).toString( ) ).info( );
183
} else if ( !bootstrap.checkRemote( ) ) {
184
EventRecord.here( Bootstrap.class, EventType.BOOTSTRAPPER_SKIPPED, currentStage.name( ), bc, "DependsRemote", comp.name( ),
185
"Component." + comp.name( ) + ".isLocal", comp.isLocal( ).toString( ) ).info( );
186
} else if ( !Components.contains( comp ) ) {
187
throw BootstrapException.throwFatal( "Bootstrap class provides a component for which registration failed: " + bc + " provides " + comp.name( ) );
189
EventRecord.here( Bootstrap.class, EventType.BOOTSTRAPPER_ADDED, currentStage.name( ), bc, "Provides", comp.name( ),
190
"Component." + comp.name( ) + ".isEnabled", comp.isEnabled( ).toString( ) ).info( );
191
Component realComponent = Components.lookup( comp );
192
realComponent.getConfiguration( ).addBootstrapper( bootstrap );
193
stage.addBootstrapper( bootstrap );
198
public static Stage transition( ) {
199
if ( currentStage == Stage.SystemInit && !loading && !starting && !finished ) {
203
} else if ( currentStage != null ) {
204
EventRecord.here( Bootstrap.class, EventType.BOOTSTRAP_STAGE_COMPLETE, currentStage.toString( ) ).info( );
205
if ( Stage.Final.equals( currentStage ) ) {
207
if ( loading && !starting && !finished ) {
211
} else if ( loading && starting && !finished ) {
219
int currOrdinal = currentStage != null ? currentStage.ordinal( ) : -1;
220
for ( int i = currOrdinal + 1; i <= Stage.Final.ordinal( ); i++ ) {
221
currentStage = Stage.values( )[i];
222
if ( currentStage.bootstrappers.isEmpty( ) ) {
223
EventRecord.here( Bootstrap.class, EventType.BOOTSTRAP_STAGE_SKIPPED, currentStage.name( ) ).info( );
232
public static Boolean isFinished( ) {
236
public static void describeComponents( String message ) {
237
LOG.info( LogUtil.header( message ) );
241
public static void initialize( ) throws Throwable {
242
LOG.info( LogUtil.header( "Initializing component resources." ) );
243
Transition.anonymous( LoadConfigs.class ).transition( Stage.list( ) );
244
for ( Component c : Components.list( ) ) {
245
LOG.info( c.toString( ) );
248
LOG.info( LogUtil.header( "Initializing discoverable bootstrap resources." ) );
249
Bootstrap.doDiscovery( );
251
LOG.info( LogUtil.header( "Initializing local singleton component services." ) );
252
Lifecycles.State.PRIMORDIAL.to( Lifecycles.State.INITIALIZED, new Committor<Component>( ) {
254
public void commit( Component comp ) throws Exception {
255
if( comp.isSingleton( ) && ( comp.isLocal( ) || comp.getPeer().equals(com.eucalyptus.bootstrap.Component.dns) ) ) {
256
comp.buildService( );
259
} ).transition( Components.list( ) );
261
Bootstrap.describeComponents( "Preparing to initialize the system." );
263
LOG.info( LogUtil.header( "Initializing bootstrappers." ) );
264
Bootstrap.initBootstrappers( );
266
Bootstrap.describeComponents( "Initialized system: ready to start bootstrap." );