forj 0.0.36 → 0.0.37
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/bin/forj +31 -32
- data/lib/boot.rb +97 -31
- data/lib/connection.rb +46 -32
- data/lib/defaults.yaml +15 -0
- data/lib/forj-config.rb +197 -65
- data/lib/repositories.rb +112 -13
- data/lib/security.rb +28 -6
- data/lib/setup.rb +228 -81
- data/lib/ssh.sh +2 -2
- metadata +5 -6
- data/lib/build_tmpl/build-env.py +0 -293
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: f8a5a5593d87c677a7565b45db486a1b840bc2b0
         | 
| 4 | 
            +
              data.tar.gz: a29f5b8d7bf6b452e9e6814a19c2f61081fc5bad
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: cbf34451071e200ccb9cc509059ad304ee8ced2e10e490d4adbdec81e132d7a52340a8a1d83a1d0ab3fe47c8add5fa63f5c730aeb6e13286400340ed4339f576
         | 
| 7 | 
            +
              data.tar.gz: 85d90986583e24d0bacb1ca2cf9a9e212d7d4b86a12fee94f084ded13a214c725c7fb5a4df382380d119af3d6fbcb5f021c3f3c1bedb6859032b0d1e63c812c3
         | 
    
        data/bin/forj
    CHANGED
    
    | @@ -23,7 +23,7 @@ require 'ansi' | |
| 23 23 | 
             
            $APP_PATH = File.dirname(__FILE__)
         | 
| 24 24 | 
             
            $LIB_PATH = File.expand_path(File.join(File.dirname($APP_PATH),'lib'))
         | 
| 25 25 |  | 
| 26 | 
            -
            $LOAD_PATH <<  | 
| 26 | 
            +
            $LOAD_PATH << $LIB_PATH
         | 
| 27 27 |  | 
| 28 28 | 
             
            require 'boot.rb'
         | 
| 29 29 | 
             
            require 'down.rb'
         | 
| @@ -47,7 +47,7 @@ include Logging | |
| 47 47 | 
             
            # Initialize forj paths
         | 
| 48 48 | 
             
            ensure_forj_dirs_exists()
         | 
| 49 49 |  | 
| 50 | 
            -
            # Initialize global Log object | 
| 50 | 
            +
            # Initialize global Log object
         | 
| 51 51 | 
             
            $FORJ_LOGGER=ForjLog.new()
         | 
| 52 52 |  | 
| 53 53 |  | 
| @@ -62,7 +62,7 @@ class Forj < Thor | |
| 62 62 | 
             
              def help(task = nil, subcommand = false)
         | 
| 63 63 | 
             
                if task
         | 
| 64 64 | 
             
                   self.class.task_help(shell, task)
         | 
| 65 | 
            -
                else | 
| 65 | 
            +
                else
         | 
| 66 66 | 
             
                   puts <<-LONGDESC
         | 
| 67 67 | 
             
            Quick steps: How to create a forj?
         | 
| 68 68 | 
             
            ----------------------------------
         | 
| @@ -71,25 +71,25 @@ Quick steps: How to create a forj? | |
| 71 71 | 
             
                `$ forj setup [Provider]`
         | 
| 72 72 |  | 
| 73 73 | 
             
                Ex: `forj setup hpcloud`. In this example, your account will be named 'hpcloud'.
         | 
| 74 | 
            -
             | 
| 75 | 
            -
            IMPORTANT NOTE: Without any provider, forj setup will choose 'hpcloud' as provider. | 
| 74 | 
            +
             | 
| 75 | 
            +
            IMPORTANT NOTE: Without any provider, forj setup will choose 'hpcloud' as provider.
         | 
| 76 76 | 
             
                            Currently, forj supports only hpcloud. Openstack will be available soon.
         | 
| 77 77 |  | 
| 78 78 | 
             
            2.  Create your forge on your default account
         | 
| 79 79 | 
             
                `$ forj boot <blueprint> on <Provider> as <InstanceName> `
         | 
| 80 80 |  | 
| 81 | 
            -
                Ex: `forj boot redstone on hpcloud as MyForge` | 
| 82 | 
            -
             | 
| 81 | 
            +
                Ex: `forj boot redstone on hpcloud as MyForge`
         | 
| 82 | 
            +
             | 
| 83 83 | 
             
            forj command line details:
         | 
| 84 84 | 
             
            --------------------------
         | 
| 85 85 | 
             
                   LONGDESC
         | 
| 86 86 | 
             
                   self.class.help(shell, subcommand)
         | 
| 87 87 | 
             
                end
         | 
| 88 | 
            -
              end | 
| 88 | 
            +
              end
         | 
| 89 89 |  | 
| 90 | 
            -
              # BOOT | 
| 90 | 
            +
              # BOOT
         | 
| 91 91 | 
             
              desc 'boot <Blueprint> on <Provider> as <InstanceName> [options]', 'boot a Maestro box and instruct it to provision the blueprint'
         | 
| 92 | 
            -
             | 
| 92 | 
            +
             | 
| 93 93 | 
             
              long_desc <<-LONGDESC
         | 
| 94 94 | 
             
            This task boot a new forge with the following options
         | 
| 95 95 | 
             
            \x5- blueprint : Is the name of the blueprint (currently cli only supports redstone)
         | 
| @@ -105,67 +105,65 @@ The list of predefined values can be retrieved with forj show defaults | |
| 105 105 |  | 
| 106 106 | 
             
              method_option :account_name,     :aliases => '-a',   :desc => 'Set the forj account name to use. By default, it takes the provider name.'
         | 
| 107 107 | 
             
              method_option :infra,            :aliases => '-i',   :desc => 'Defines your Infra directory to use while booting. You can also set FORJ_INFRA_DIR.'
         | 
| 108 | 
            +
              method_option :maestro_repo,     :aliases => '-m',   :desc => 'To use a different Maestro repository already cloned. By default, Maestro is cloned to ~/.forj/maestro from github.'
         | 
| 108 109 | 
             
              method_option :key_name,         :aliases => '-k',   :desc => "Keypair name to use."
         | 
| 109 110 | 
             
              method_option :key_path,         :aliases => '-p',   :desc => "Private or Public key file. forj will determine if you provide a public key or a private, if respectively the extension '.pub' exist or not."
         | 
| 110 111 |  | 
| 111 112 | 
             
              method_option :boothook,         :aliases => '-H',   :desc => 'By default, boothook file used is build/bin/build-tools/boothook.sh. Use this option to set another one.'
         | 
| 112 113 | 
             
              method_option :build,            :aliases => '-B',   :desc => 'Replace the default build.sh'
         | 
| 113 | 
            -
              method_option :build_config,     :aliases => '-C',   :desc => 'The build config file to load <confdir>/<BoxName>.<Config>.env. By default, uses "master" as Config.'
         | 
| 114 | 
            -
              method_option :maestro_repo,     :aliases => '-M',   :desc => 'To use a different Maestro repository already cloned. By default, Maestro is cloned to ~/.forj/maestro from github.'
         | 
| 115 114 | 
             
              method_option :branch,           :aliases => '-B',   :desc => 'The build will extract from git branch name. It sets the configuration build <config> to the branch name <branch>.'
         | 
| 116 | 
            -
              method_option :box_name,         :aliases => '-N',   :desc => 'Defines the name of the box or box image to build.'
         | 
| 117 115 | 
             
              method_option :test_box,         :aliases => '-T',   :desc => 'Create test.rb-box meta from the repository path provided.'
         | 
| 118 | 
            -
             | 
| 119 | 
            -
              def boot(blueprint, on, cloud_provider, as, name | 
| 116 | 
            +
             | 
| 117 | 
            +
              def boot(blueprint, on, cloud_provider, as, name)
         | 
| 120 118 | 
             
                  Logging.set_level(Logger::INFO) if options[:verbose]
         | 
| 121 119 | 
             
                  Logging.set_level(Logger::DEBUG) if options[:debug]
         | 
| 122 120 | 
             
                  oConfig=ForjConfig.new(options[:config])
         | 
| 123 | 
            -
             | 
| 121 | 
            +
             | 
| 124 122 | 
             
                  Logging.fatal(1, "instance name '%s' not supported. Support only lower case, numeric and dash caracters." % [name]) if not /^[\d[[:lower:]]-]+$/ =~ name
         | 
| 125 | 
            -
             | 
| 123 | 
            +
             | 
| 126 124 | 
             
                  # Options are added if they are set. Otherwise, get will retrieve the default value.
         | 
| 127 125 | 
             
                  oConfig.set('account_name', options[:account_name])
         | 
| 128 126 | 
             
                  oConfig.set('infra_repo',   options[:infra])
         | 
| 129 127 | 
             
                  oConfig.set('keypair_name', options[:key_name])
         | 
| 130 128 | 
             
                  if options[:key_path]
         | 
| 131 129 | 
             
                     mFound = options[:key_path].match(/^(.*)(\.pub)?$/)
         | 
| 132 | 
            -
                     if mFound | 
| 130 | 
            +
                     if mFound
         | 
| 133 131 | 
             
                        key_path = File.expand_path(mFound[1])
         | 
| 134 132 | 
             
                        if mFound[2] and not File.exists?(File.expand_path(mFound[1]+mFound[2]))
         | 
| 135 133 | 
             
                           Logging.fatal(1, "'%s' is not a valid keypair files. At least the public key (.pub) is have to exist.")
         | 
| 136 | 
            -
                        end | 
| 134 | 
            +
                        end
         | 
| 137 135 | 
             
                        oConfig.set('keypair_path', key_path)
         | 
| 138 136 | 
             
                     else
         | 
| 139 137 | 
             
                        Logging.fatal(1, "'%s' is not a valid keypair files. At least the public key (.pub) is have to exist.")
         | 
| 140 | 
            -
                     end | 
| 141 | 
            -
                  end | 
| 138 | 
            +
                     end
         | 
| 139 | 
            +
                  end
         | 
| 142 140 |  | 
| 143 141 | 
             
                  # TODO: Be able to support the default provider from config.yaml
         | 
| 144 142 | 
             
                  oConfig.set('provider', cloud_provider)
         | 
| 145 143 | 
             
                  Boot.boot(blueprint, name,
         | 
| 146 | 
            -
                            options[:build], | 
| 144 | 
            +
                            options[:build],
         | 
| 147 145 | 
             
                            options[:build_config], options[:branch],
         | 
| 148 146 | 
             
                            options[:maestro_repo], options[:boothook],
         | 
| 149 | 
            -
                            options[:box_name], oConfig | 
| 147 | 
            +
                            options[:box_name], oConfig)
         | 
| 150 148 | 
             
              end
         | 
| 151 149 |  | 
| 152 150 | 
             
              desc 'show defaults', 'Show list of predefined value you can update in your ~/.forj/config.yaml'
         | 
| 153 151 |  | 
| 154 152 | 
             
              def show(name)
         | 
| 155 153 | 
             
                 oConfig=ForjConfig.new()
         | 
| 156 | 
            -
             | 
| 157 | 
            -
                 puts 'List of  | 
| 154 | 
            +
             | 
| 155 | 
            +
                 puts 'List of default values:
         | 
| 158 156 | 
             
            --------------------------'
         | 
| 159 | 
            -
                 puts oConfig. | 
| 157 | 
            +
                 puts rhGet(oConfig.yConfig,'default').to_yaml()
         | 
| 160 158 | 
             
                 puts '--------------------------'
         | 
| 161 | 
            -
                 puts "You can  | 
| 159 | 
            +
                 puts "You can change any of those variables by editing/adding them in your ~/.forj/config.yaml, under section 'default:'"
         | 
| 162 160 | 
             
              end
         | 
| 163 161 | 
             
              # DOWN
         | 
| 164 162 | 
             
              desc 'down', 'delete the Maestro box and all systems installed by the blueprint'
         | 
| 165 163 | 
             
              long_desc <<-LONGDESC
         | 
| 166 164 | 
             
              Not yet implemented
         | 
| 167 165 | 
             
              LONGDESC
         | 
| 168 | 
            -
             | 
| 166 | 
            +
             | 
| 169 167 | 
             
              def down(name)
         | 
| 170 168 | 
             
                  Logging.set_level(Logger::INFO) if options[:verbose]
         | 
| 171 169 | 
             
                Logging.set_level(Logger::DEBUG) if options[:debug]
         | 
| @@ -176,17 +174,17 @@ The list of predefined values can be retrieved with forj show defaults | |
| 176 174 | 
             
              desc 'ssh', 'connect to your forge thru ssh'
         | 
| 177 175 | 
             
              long_desc <<-LONGDESC
         | 
| 178 176 | 
             
            Connect through ssh to an existing instance
         | 
| 179 | 
            -
             | 
| 177 | 
            +
             | 
| 180 178 | 
             
                    not yet implemented
         | 
| 181 179 | 
             
              LONGDESC
         | 
| 182 | 
            -
             | 
| 180 | 
            +
             | 
| 183 181 | 
             
              def ssh(name, server)
         | 
| 184 182 | 
             
                Logging.set_level(Logger::INFO) if options[:verbose]
         | 
| 185 183 | 
             
                Logging.set_level(Logger::DEBUG) if options[:debug]
         | 
| 186 184 | 
             
                Ssh.connect(name, server)
         | 
| 187 185 | 
             
              end
         | 
| 188 186 |  | 
| 189 | 
            -
              # SETUP | 
| 187 | 
            +
              # SETUP
         | 
| 190 188 | 
             
              method_option :account_name,     :aliases => '-a',   :desc => 'Set the forj account name to use. By default, it takes the provider name.'
         | 
| 191 189 |  | 
| 192 190 | 
             
              desc 'setup [Provider] [options]', 'set the hpcloud credentials for forj cli'
         | 
| @@ -204,7 +202,8 @@ Several data will be requested like: | |
| 204 202 | 
             
                Logging.set_level(Logger::INFO)  if options[:verbose]
         | 
| 205 203 | 
             
                Logging.set_level(Logger::DEBUG) if options[:debug]
         | 
| 206 204 | 
             
                oConfig=ForjConfig.new(options[:config])
         | 
| 207 | 
            -
                 | 
| 205 | 
            +
                oConfig.set('provider', sProvider)
         | 
| 206 | 
            +
                Setup.setup(oConfig, options)
         | 
| 208 207 | 
             
              end
         | 
| 209 208 |  | 
| 210 209 | 
             
            end
         | 
    
        data/lib/boot.rb
    CHANGED
    
    | @@ -34,10 +34,9 @@ include Helpers | |
| 34 34 | 
             
            # Boot module
         | 
| 35 35 | 
             
            #
         | 
| 36 36 | 
             
            module Boot
         | 
| 37 | 
            -
              def boot(blueprint, name,
         | 
| 38 | 
            -
                  build, infra_dir, build_config,
         | 
| 37 | 
            +
              def boot(blueprint, name, build, build_config,
         | 
| 39 38 | 
             
                  branch, maestro_repo, boothook, box_name,
         | 
| 40 | 
            -
                  oConfig | 
| 39 | 
            +
                  oConfig)
         | 
| 41 40 | 
             
                begin
         | 
| 42 41 |  | 
| 43 42 | 
             
                  # Check options and set data
         | 
| @@ -48,7 +47,7 @@ module Boot | |
| 48 47 | 
             
                     Logging.fatal(1, "forj setup support only hpcloud. '%s' is currently not supported." % cloud_provider)
         | 
| 49 48 | 
             
                  end
         | 
| 50 49 |  | 
| 51 | 
            -
                  oConfig. | 
| 50 | 
            +
                  oConfig.set('account_name', cloud_provider)
         | 
| 52 51 |  | 
| 53 52 | 
             
                  initial_msg = 'booting %s on %s (~/.forj/forj.log)' % [blueprint , cloud_provider]
         | 
| 54 53 | 
             
                  Logging.high_level_msg(initial_msg) #################
         | 
| @@ -56,21 +55,31 @@ module Boot | |
| 56 55 | 
             
                  # Initialize defaults
         | 
| 57 56 | 
             
                  maestro_url =  oConfig.get('maestro_url')
         | 
| 58 57 |  | 
| 59 | 
            -
                  infra_dir = oConfig.get('infra_repo') | 
| 58 | 
            +
                  infra_dir = File.expand_path(oConfig.get('infra_repo'))
         | 
| 59 | 
            +
                  
         | 
| 60 | 
            +
                  # Load Forj account data
         | 
| 61 | 
            +
                  forjAccountFile = File.join($FORJ_ACCOUNTS_PATH, oConfig.get('account_name'))
         | 
| 62 | 
            +
                  oConfig.ExtraLoad(forjAccountFile, :forj_accounts, oConfig.get('account_name'))
         | 
| 60 63 |  | 
| 64 | 
            +
                  # Check about infra repo compatibility with forj cli
         | 
| 65 | 
            +
                  bBuildInfra = Repositories.infra_rebuild_required?(oConfig, infra_dir)
         | 
| 66 | 
            +
                  
         | 
| 61 67 | 
             
                  # Ask information if needed.
         | 
| 62 | 
            -
                  bBuildInfra=false
         | 
| 63 68 | 
             
                  if not Dir.exist?(File.expand_path(infra_dir))
         | 
| 64 69 | 
             
                     sAsk = 'Your \'%s\' infra directory doesn\'t exist. Do you want to create a new one from Maestro(repo github)/templates/infra (yes/no)?' % [infra_dir]
         | 
| 65 70 | 
             
                     bBuildInfra=agree(sAsk)
         | 
| 66 71 | 
             
                  else
         | 
| 67 | 
            -
                     Logging.info('Re-using your infra... in \'%s\'' % [infra_dir])
         | 
| 72 | 
            +
                     Logging.info('Re-using your infra... in \'%s\'' % [infra_dir]) if not bBuildInfra
         | 
| 68 73 | 
             
                  end
         | 
| 69 74 | 
             
                  if not Dir.exist?(File.expand_path(infra_dir)) and not bBuildInfra
         | 
| 70 75 | 
             
                     Logging.info ('Exiting.')
         | 
| 71 76 | 
             
                     return
         | 
| 72 77 | 
             
                  end
         | 
| 73 78 |  | 
| 79 | 
            +
                  # Get FORJ DNS setting
         | 
| 80 | 
            +
                  yDNS = oConfig.ExtraGet(:forj_accounts, oConfig.get('account_name'), :dns)
         | 
| 81 | 
            +
                  Logging.fatal(1, "DNS or domain name are missing. Please execute forj setup %s" % oConfig.get('account_name')) if not yDNS
         | 
| 82 | 
            +
             | 
| 74 83 | 
             
                  # Step Maestro Clone
         | 
| 75 84 | 
             
                  if not maestro_repo
         | 
| 76 85 | 
             
                     Logging.high_level_msg('cloning maestro repo ...' ) #################
         | 
| @@ -105,7 +114,7 @@ module Boot | |
| 105 114 |  | 
| 106 115 | 
             
                  Logging.state('Configuring keypair...') #################
         | 
| 107 116 | 
             
                  Logging.info('Configuring keypair \'%s\'' % [oConfig.get('keypair_name')])
         | 
| 108 | 
            -
                  SecurityGroup. | 
| 117 | 
            +
                  SecurityGroup.hpc_import_key(oConfig, oFC.sAccountName)
         | 
| 109 118 |  | 
| 110 119 | 
             
                  Logging.state('Configuring security group...') #################
         | 
| 111 120 |  | 
| @@ -116,55 +125,65 @@ module Boot | |
| 116 125 | 
             
                  Logging.state('Configuring security group ports...') #################
         | 
| 117 126 | 
             
                  ports.each do |port|
         | 
| 118 127 | 
             
                    port = port.to_s if port.class != String
         | 
| 119 | 
            -
                    if not /^\d+(-\d+)?$/ =~ port | 
| 128 | 
            +
                    if not /^\d+(-\d+)?$/ =~ port
         | 
| 120 129 | 
             
                       Logging.error("Port '%s' is not valid. Must be <Port> or <PortMin>-<PortMax>" % [port])
         | 
| 121 | 
            -
                    else | 
| 130 | 
            +
                    else
         | 
| 122 131 | 
             
                       mPortFound = /^(\d+)(-(\d+))?$/.match(port)
         | 
| 123 132 | 
             
                       portmin = mPortFound[1]
         | 
| 124 133 | 
             
                       portmax = (mPortFound[3]) ? (mPortFound[3]) : (portmin)
         | 
| 125 134 | 
             
                       Network.get_or_create_rule(oFC, security_group.id, 'tcp', portmin, portmax)
         | 
| 126 | 
            -
                    end | 
| 135 | 
            +
                    end
         | 
| 127 136 | 
             
                  end
         | 
| 128 137 |  | 
| 129 | 
            -
                   | 
| 130 | 
            -
                  ENV[' | 
| 131 | 
            -
                   | 
| 132 | 
            -
                   | 
| 133 | 
            -
                   | 
| 134 | 
            -
                   | 
| 138 | 
            +
                  oBuildEnv = BuildEnv.new(oConfig)
         | 
| 139 | 
            +
                  ENV['FORJ_CLI_ENV'] = oBuildEnv.sBuildEnvFile
         | 
| 140 | 
            +
                  oBuildEnv.set('FORJ_HPC',             oFC.sAccountName)
         | 
| 141 | 
            +
                  oBuildEnv.set('FORJ_HPC_NET',         network.name)
         | 
| 142 | 
            +
                  oBuildEnv.set('FORJ_SECURITY_GROUP',  oConfig.get('security_group'))
         | 
| 143 | 
            +
                  oBuildEnv.set('FORJ_KEYPAIR',         oConfig.get('keypair_name'))
         | 
| 144 | 
            +
                  oBuildEnv.set('FORJ_HPC_NOVA_KEYPUB', oConfig.get('keypair_path') + '.pub')
         | 
| 145 | 
            +
                  oBuildEnv.set('FORJ_BASE_IMG',        oConfig.get('image'))
         | 
| 146 | 
            +
                  oBuildEnv.set('FORJ_FLAVOR',          oConfig.get('flavor'))
         | 
| 147 | 
            +
                  oBuildEnv.set('FORJ_TENANT_NAME',     rhGet(oConfig.ExtraGet(:forj_accounts, oFC.sAccountName, :compute), :tenant_name))
         | 
| 148 | 
            +
                  
         | 
| 149 | 
            +
             | 
| 150 | 
            +
                  oBuildEnv.set('FORJ_DOMAIN', yDNS[:domain_name])
         | 
| 151 | 
            +
             | 
| 152 | 
            +
                  if yDNS[:tenant_id]
         | 
| 153 | 
            +
                     oBuildEnv.set('FORJ_DNS_TENANTID', yDNS[:tenant_id])
         | 
| 154 | 
            +
                     oBuildEnv.set('FORJ_DNS_ZONE',     yDNS[:service])
         | 
| 155 | 
            +
                  end
         | 
| 156 | 
            +
                  oBuildEnv.save()
         | 
| 135 157 |  | 
| 136 158 | 
             
                  # run build.sh to boot maestro
         | 
| 137 159 | 
             
                  puts
         | 
| 138 160 |  | 
| 139 161 | 
             
                  build = 'bin/build.sh' unless build
         | 
| 140 162 |  | 
| 141 | 
            -
                  build_config = oConfig.get('build_config') | 
| 142 | 
            -
             | 
| 163 | 
            +
                  build_config = oConfig.get('build_config')
         | 
| 143 164 | 
             
                  branch = oConfig.get('branch') unless branch
         | 
| 144 | 
            -
             | 
| 145 | 
            -
                  box_name = oConfig.get('box_name') unless box_name
         | 
| 165 | 
            +
                  box_name = oConfig.get('box_name')
         | 
| 146 166 |  | 
| 147 167 | 
             
                  meta = '--meta blueprint=%s ' % [blueprint]
         | 
| 148 168 |  | 
| 149 169 | 
             
                  command = '%s --build_ID %s --box-name %s --build-conf-dir %s --build-config %s --gitBranch %s --debug-box %s' % [build, name, box_name, infra_dir, build_config, branch, meta]
         | 
| 150 170 |  | 
| 151 | 
            -
                  maestro_build_path = File. | 
| 171 | 
            +
                  maestro_build_path = File.join(maestro_repo, 'build')
         | 
| 152 172 |  | 
| 153 173 | 
             
                  current_dir = Dir.pwd
         | 
| 154 | 
            -
             | 
| 155 | 
            -
                  Dir.chdir(File.expand_path('~/.forj/maestro/build'))
         | 
| 174 | 
            +
                  Dir.chdir(maestro_build_path)
         | 
| 156 175 |  | 
| 157 176 | 
             
                  Logging.info("Calling '%s' from '%s'" %  [build, Dir.pwd])
         | 
| 158 | 
            -
                  Logging.debug(command)
         | 
| 177 | 
            +
                  Logging.debug("%s=%s %s" % ['FORJ_CLI_ENV', ENV['FORJ_CLI_ENV'], command])
         | 
| 159 178 | 
             
                  Kernel.system(ENV, command)
         | 
| 160 179 | 
             
                  Dir.chdir(current_dir)
         | 
| 161 180 |  | 
| 162 | 
            -
                  if test
         | 
| 163 | 
            -
                    Logging.debug 'test flag is on, deleting objects'
         | 
| 164 | 
            -
                    Network.delete_router_interface(subnet.id, router)
         | 
| 165 | 
            -
                    Network.delete_subnet(subnet.id)
         | 
| 166 | 
            -
                    Network.delete_network(network.name)
         | 
| 167 | 
            -
                  end
         | 
| 181 | 
            +
            #      if test
         | 
| 182 | 
            +
            #        Logging.debug 'test flag is on, deleting objects'
         | 
| 183 | 
            +
            #        Network.delete_router_interface(subnet.id, router)
         | 
| 184 | 
            +
            #        Network.delete_subnet(subnet.id)
         | 
| 185 | 
            +
            #        Network.delete_network(network.name)
         | 
| 186 | 
            +
            #      end
         | 
| 168 187 |  | 
| 169 188 | 
             
                rescue Interrupt
         | 
| 170 189 | 
             
                  Logging.message("\n'%s' boot from '%s' interrupted by user" % [name, blueprint])
         | 
| @@ -172,4 +191,51 @@ module Boot | |
| 172 191 | 
             
                  Logging.error("%s\n%s" % [e.message, e.backtrace.join("\n")])
         | 
| 173 192 | 
             
                end
         | 
| 174 193 | 
             
              end
         | 
| 194 | 
            +
             | 
| 195 | 
            +
            end
         | 
| 196 | 
            +
             | 
| 197 | 
            +
             | 
| 198 | 
            +
            class BuildEnv
         | 
| 199 | 
            +
             | 
| 200 | 
            +
               attr_reader :sBuildEnvFile
         | 
| 201 | 
            +
               
         | 
| 202 | 
            +
               def initialize(oConfig)
         | 
| 203 | 
            +
             | 
| 204 | 
            +
                  oConfig.fatal_if_inexistent('infra_repo')
         | 
| 205 | 
            +
                  oConfig.fatal_if_inexistent('account_name')
         | 
| 206 | 
            +
             | 
| 207 | 
            +
                  sBuildDir = File.expand_path(File.join(oConfig.get('infra_repo'),'build'))
         | 
| 208 | 
            +
                  @sBuildEnvFile = File.join(sBuildDir, oConfig.get('account_name')+'.build.env')
         | 
| 209 | 
            +
                  Helpers.ensure_dir_exists(sBuildDir)
         | 
| 210 | 
            +
                  @yBuildEnvVar = {}
         | 
| 211 | 
            +
                  @oConfig = oConfig
         | 
| 212 | 
            +
               end
         | 
| 213 | 
            +
             | 
| 214 | 
            +
               def set(key, value)
         | 
| 215 | 
            +
                  # This file creates the in-memory data required to configure specific project build_env.
         | 
| 216 | 
            +
                  # Name : ~/.forj/account/<Account>.build.env
         | 
| 217 | 
            +
                  if value
         | 
| 218 | 
            +
                     Logging.debug("Setting '%s' = '%s'" % [key, value])
         | 
| 219 | 
            +
                     @yBuildEnvVar[key] = value
         | 
| 220 | 
            +
                  else
         | 
| 221 | 
            +
                     Logging.debug("'%s' is not set" % [key])
         | 
| 222 | 
            +
                  end
         | 
| 223 | 
            +
               end
         | 
| 224 | 
            +
             | 
| 225 | 
            +
               def save()
         | 
| 226 | 
            +
                  begin
         | 
| 227 | 
            +
                     File.open(@sBuildEnvFile, 'w') do |out|
         | 
| 228 | 
            +
                        @yBuildEnvVar.each do | key, value |
         | 
| 229 | 
            +
                           if rhExist?(@oConfig.yConfig, 'description', key)
         | 
| 230 | 
            +
                              out.write("# %s - %s\n" % [key, rhGet(@oConfig.yConfig, 'description', key)])
         | 
| 231 | 
            +
                           end
         | 
| 232 | 
            +
                           value = "" if not value
         | 
| 233 | 
            +
                           out.write("%s='%s'\n\n" % [key, value])
         | 
| 234 | 
            +
                        end
         | 
| 235 | 
            +
                     end
         | 
| 236 | 
            +
                     Logging.debug("'%s' written." % [@sBuildEnvFile])
         | 
| 237 | 
            +
                  rescue => e
         | 
| 238 | 
            +
                     Logging.error("%s\n%s" % [e.message, e.backtrace.join("\n")])
         | 
| 239 | 
            +
                  end
         | 
| 240 | 
            +
               end
         | 
| 175 241 | 
             
            end
         | 
    
        data/lib/connection.rb
    CHANGED
    
    | @@ -32,17 +32,29 @@ class ForjConnection | |
| 32 32 | 
             
               attr_accessor :oNetwork
         | 
| 33 33 | 
             
               attr_accessor :sAccountName
         | 
| 34 34 |  | 
| 35 | 
            -
               def initialize(oConfig)
         | 
| 35 | 
            +
               def initialize(oConfig, bAutoConnect = true)
         | 
| 36 36 |  | 
| 37 | 
            -
                  | 
| 37 | 
            +
                 Logging.fatal(1, 'Internal Error: Missing global $HPC_ACCOUNTS') if not $HPC_ACCOUNTS
         | 
| 38 | 
            +
                 
         | 
| 39 | 
            +
                 @oConfig = oConfig
         | 
| 40 | 
            +
                 @sAccountName = @oConfig.get('account_name')
         | 
| 38 41 | 
             
                 @provider='HP' # TODO: Support multiple provider. (Generic Provider object required)
         | 
| 39 | 
            -
                 @sAccountName = oConfig.get('provider') if not @sAccountName
         | 
| 42 | 
            +
                 @sAccountName = @oConfig.get('provider') if not @sAccountName
         | 
| 40 43 | 
             
                 @sAccountName = 'hpcloud' if not @sAccountName
         | 
| 41 44 |  | 
| 42 | 
            -
                 @credentials = get_credentials( | 
| 43 | 
            -
                 oSSLError=SSLErrorMgt.new
         | 
| 45 | 
            +
                 @credentials = get_credentials()
         | 
| 44 46 |  | 
| 45 47 | 
             
                 # Trying to get Compute object
         | 
| 48 | 
            +
                 compute_connect if bAutoConnect
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                 # Trying to get Network object
         | 
| 51 | 
            +
                 network_connect if bAutoConnect
         | 
| 52 | 
            +
             | 
| 53 | 
            +
               end
         | 
| 54 | 
            +
             | 
| 55 | 
            +
               def compute_connect
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                 oSSLError=SSLErrorMgt.new # Retry object
         | 
| 46 58 |  | 
| 47 59 | 
             
                 Logging.debug("compute: Connecting to '%s' - Project '%s'" % [@provider, @credentials['tenant_id']])
         | 
| 48 60 | 
             
                 begin
         | 
| @@ -59,10 +71,13 @@ class ForjConnection | |
| 59 71 | 
             
                   if not oSSLError.ErrorDetected(e.message,e.backtrace)
         | 
| 60 72 | 
             
                      retry
         | 
| 61 73 | 
             
                   end
         | 
| 62 | 
            -
                   Logging.fatal(1, 'Unable to connect.')
         | 
| 74 | 
            +
                   Logging.fatal(1, 'Compute: Unable to connect.')
         | 
| 63 75 | 
             
                 end
         | 
| 64 | 
            -
             | 
| 76 | 
            +
               end
         | 
| 77 | 
            +
               
         | 
| 78 | 
            +
               def network_connect
         | 
| 65 79 | 
             
                 # Trying to get Network object
         | 
| 80 | 
            +
                 oSSLError=SSLErrorMgt.new # Retry object
         | 
| 66 81 | 
             
                 Logging.debug("HP network: Connecting to '%s' - Project '%s'" % [@provider, @credentials['tenant_id']])
         | 
| 67 82 | 
             
                 begin
         | 
| 68 83 | 
             
                   @oNetwork=Fog::HP::Network.new({
         | 
| @@ -76,34 +91,33 @@ class ForjConnection | |
| 76 91 | 
             
                   if not oSSLError.ErrorDetected(e.message,e.backtrace)
         | 
| 77 92 | 
             
                      retry
         | 
| 78 93 | 
             
                   end
         | 
| 79 | 
            -
                   Logging.fatal(1, 'Unable to connect.')
         | 
| 94 | 
            +
                   Logging.fatal(1, 'Network: Unable to connect.')
         | 
| 80 95 | 
             
                 end
         | 
| 81 96 |  | 
| 82 97 | 
             
               end
         | 
| 83 98 |  | 
| 84 | 
            -
             | 
| 99 | 
            +
               def get_credentials()
         | 
| 100 | 
            +
                 # TODO: Should support forj credentials. not hpcloud credentials.
         | 
| 101 | 
            +
             | 
| 102 | 
            +
                 creds = File.join($HPC_ACCOUNTS, @sAccountName)
         | 
| 103 | 
            +
                 if not File.exists?(creds)
         | 
| 104 | 
            +
                    Logging.fatal(1, "'%s' was not configured. Did you executed 'forj setup %s'? Please do it and retry." % [@sAccountName, @sAccountName])
         | 
| 105 | 
            +
                 end
         | 
| 106 | 
            +
                 @oConfig.ExtraLoad(creds, :hpc_accounts, @sAccountName)
         | 
| 107 | 
            +
             | 
| 108 | 
            +
                 template = @oConfig.ExtraGet(:hpc_accounts, @sAccountName)
         | 
| 109 | 
            +
                 credentials = {}
         | 
| 110 | 
            +
                 begin
         | 
| 111 | 
            +
                   credentials['access_key'] = template[:credentials][:account_id]
         | 
| 112 | 
            +
                   credentials['secret_key'] = template[:credentials][:secret_key]
         | 
| 113 | 
            +
                   credentials['auth_uri'] = template[:credentials][:auth_uri]
         | 
| 114 | 
            +
                   credentials['tenant_id'] = template[:credentials][:tenant_id]
         | 
| 115 | 
            +
                   credentials['availability_zone'] = template[:regions][:compute]
         | 
| 116 | 
            +
                 rescue => e
         | 
| 117 | 
            +
                   Logging.error("%s\n%s" % [e.message, e.backtrace.join("\n")])
         | 
| 118 | 
            +
                   puts 'your credentials are not configured, delete the file %s and run forj setup again' % [creds]
         | 
| 119 | 
            +
                 end
         | 
| 120 | 
            +
                 credentials
         | 
| 121 | 
            +
               end
         | 
| 85 122 |  | 
| 86 | 
            -
            def get_credentials(sAccountName)
         | 
| 87 | 
            -
              # TODO: Should support forj credentials. not hpcloud credentials.
         | 
| 88 | 
            -
             | 
| 89 | 
            -
              Logging.fatal(1, 'Internal Error: Missing sAccountName') if not sAccountName
         | 
| 90 | 
            -
             | 
| 91 | 
            -
              creds = File.expand_path('~/.hpcloud/accounts/%s' % [sAccountName])
         | 
| 92 | 
            -
              if not File.exists?(creds)
         | 
| 93 | 
            -
                 Logging.fatal(1, "'%s' was not configured. Did you executed 'forj setup %s'? Please do it and retry." % [sAccountName, sAccountName])
         | 
| 94 | 
            -
              end
         | 
| 95 | 
            -
              template = YAML.load_file(creds)
         | 
| 96 | 
            -
              credentials = Hash.new
         | 
| 97 | 
            -
             | 
| 98 | 
            -
              begin
         | 
| 99 | 
            -
                credentials['access_key'] = template[:credentials][:account_id]
         | 
| 100 | 
            -
                credentials['secret_key'] = template[:credentials][:secret_key]
         | 
| 101 | 
            -
                credentials['auth_uri'] = template[:credentials][:auth_uri]
         | 
| 102 | 
            -
                credentials['tenant_id'] = template[:credentials][:tenant_id]
         | 
| 103 | 
            -
                credentials['availability_zone'] = template[:regions][:compute]
         | 
| 104 | 
            -
              rescue => e
         | 
| 105 | 
            -
                Logging.error("%s\n%s" % [e.message, e.backtrace.join("\n")])
         | 
| 106 | 
            -
                puts 'your credentials are not configured, delete the file %s and run forj setup again' % [creds]
         | 
| 107 | 
            -
              end
         | 
| 108 | 
            -
              credentials
         | 
| 109 123 | 
             
            end
         | 
    
        data/lib/defaults.yaml
    CHANGED
    
    | @@ -39,3 +39,18 @@ default: | |
| 39 39 | 
             
              build_config: box
         | 
| 40 40 | 
             
              branch: master
         | 
| 41 41 | 
             
              box_name: maestro
         | 
| 42 | 
            +
            description:
         | 
| 43 | 
            +
              # Description of build.sh environment variable defined by forj cli for build.sh. (~/.forj/infra/build/<Account>.build.env)
         | 
| 44 | 
            +
              FORJ_HPC:             "HPCloud cli Account used to build your Maestro box"
         | 
| 45 | 
            +
              FORJ_HPC_COMPUTE:     "HPCloud Compute service (like region-b.geo-1) used to run your Maestro Box"
         | 
| 46 | 
            +
              FORJ_TENANT_NAME:     "HPCloud Tenant name used build your <Blueprint> nodes"
         | 
| 47 | 
            +
              FORJ_HPC_NET:         "HPCloud Network name to use, while booting all boxes."
         | 
| 48 | 
            +
              FORJ_KEYPAIR:         "Keypair used to access boxes."
         | 
| 49 | 
            +
              FORJ_SECURITY_GROUP:  "Security group associated to each box"
         | 
| 50 | 
            +
              FORJ_HPC_NOVA_KEYPUB: "Public key used by build.sh to ensure his existence on HPCloud"
         | 
| 51 | 
            +
              FORJ_BASE_IMG:        "Base image used to build all boxes"
         | 
| 52 | 
            +
              FORJ_FLAVOR:          "Flavor used to build Maestro"
         | 
| 53 | 
            +
              # DNS specific data
         | 
| 54 | 
            +
              FORJ_DNS_TENANTID:    "HPCloud Project ID to use to create DNS entries for each boxes."
         | 
| 55 | 
            +
              FORJ_DNS_ZONE:        "HPCloud Domain name service to use for each boxes DNS entries. (Ex: region-a.geo-1)"
         | 
| 56 | 
            +
              FORJ_DNS_DOMAIN:      "Domain used for DNS. Each server will be attached to a public IP. An 'A' record in the DNS service will need to be added to your HPCloud DOMAIN."
         |