Coder Social home page Coder Social logo

cloudenvy's Introduction

cloudenvy

The goal of cloudenvy is to allow developers to easily spin up instances for development in an OpenStack cloud.

cloudenvy is built on a few principles.

1. Bootstrapping an environment should only take 1 command.
2. Hardware is the enemy, virtualize your environments so others can play with you.
3. Never rely on tools which you can not hack.

Installation

Use setup.py to install cloudenvy and the dependencies:

python setup.py install

Configuration

User Config

You must set your user options in ~/.cloudenvy.yml. User options include a few general preferences, and your cloud credentials. Here is a minimal config:

cloudenvy:
  clouds:
    cloud01:
      os_username: username
      os_password: password
      os_tenant_name: tenant_name
      os_auth_url: http://keystone.example.com:5000/v2.0/

      # Optional
      #os_region_name: RegionOne

Project Config

Much like Vagrant, each Envy must have a corresponding configuration file in the project working directory. We call this file Envyfile. It should be located at Envyfile.yml the root of your project.

project_config:
  name: foo
  image: Ubuntu 12.04 cloudimg amd64

  # Optional
  #remote_user: ubuntu
  #flavor_name: m1.small
  #auto_provision: False
  provision_scripts:
    #- provision_script.sh

NOTE: For the image property you can use either an image name or an id. If you use a development cloud where ids change frequently its probably better to use the image name, in all other cases we recommend you use an image id... but it is your call.

Usage

Launch

Launch a bare instance

envy up

NOTE: If your Envyfile contains the provision_scripts config option, envy up will automatically run envy provision when your Envy has finished booting. If you do not want to auto provision your Envy you must pass the --no-provision flag like so:

envy up --no-provision

NOTE: If your Envyfile contains the files config option, envy will automatically run envy files when your Envy has finished booting, before envy provision is run. If you do not want to automatically put your files on the new instance, you must pass the --no-files flag:

envy up --no-files

NOTE: Use the -v flag to get verbose logging output. Example: envy -v up

NOTE: CloudEnvy sets certain metadata (such as os_auth_url) on the instance at launch time to make provisioning and other post-launch tasks more developer-friendly.

Files

Files can be placed onto the new instance. The files work with a files hash in your Envyfile.

#...
files:
  README.md: '~'

The key of the hash is the local path relative to your Envyfile, or absolute, and the value is the remote location. Files and directories are accepted, according to the same restrictions as Fabric's put directive.

To invoke the file uploads directly you can run:

envy files

If your remote machine doesn't have sudo installed, and since cloudenvy uses sudo when pushing files to your remote machine, you can optionnaly turn the use of sudo off by using files_use_sudo: False.

#...
files_use_sudo: False
files:
  README.md: '~'

Provision

To provision a script, you must set the path to one or more shell scripts (in the future these can be any type of excecutable files).

envy provision

If you are attempting to debug provision scripts, you can pass in several scripts, which will be run in order, like so:

envy provision --scripts ~/Desktop/scripts/foo.sh ~/Desktop/scripts/bar.sh

NOTE: Provisioning an Envy does not use the OpenStack CloudConfigDrive. Instead it uploads the provision script, and runs it using Fabric. This allows you to perform operations which require ssh authentication (such as a git clone from a private repository)

Get your Envy IP

envy ip

SSH to your Envy

SSH into your instance.

envy ssh

NOTE: It is highly recommended that you enable SSH Agent Forwarding. The fastest way to do this is to run:

ssh-add

Run a command on your Envy

envy run "ls ~/foo"

Destroy your Envy

Destroy your instance

envy destroy

Advanced cloudenvy

Name your Envys

If desired you can launch multiple Envys for a single project. This is useful if you want to run an Envy for development, and a separate Envy for testing. Your Envy name will always be prefaced for the project it belongs to, to do this run:

envy up -n foo #this will result in ProjectName-foo

NOTE: If you choose to do this, you will need to pass the -n flag into all of your commands, for example if you want to ssh into the Envy created above you would have to run:

envy ssh -n foo

You will quickly lose track of all of the Envys for your project, so we added a command that will allow you to retrieve each Envy name in context of your proejct. To do this run:

envy list

NOTE: This will likely change, as cloudenvy gets smarter in how it tracks instances, for example we should probably be using server metadata to track if an instance is from cloudenvy.

Passing in your user configuration (dotfiles)

You can pass in basic dotfiles by running:

envy dotfiles

This defaults to uploading the following files .vimrc, .gitconfig, .gitignore, .screenrc. If you would like to pass in a custom set of dotfiles, you can specify them like so

envy dotfiles -f '.vimrc, .gitconfig'

NOTE: The custom dotfiles must be in a comma separated list, and all of them in a single set of quotes.

Simple file uploading

You can upload files to your Envy via SFTP by running:

envy scp ~/cat-photo.jpg ~/ZOMGKITTY.jpg

Defining custom security groups

By default cloudenvy opens ports 22, 443, 80, 8080, 5000, and 9292. These ports are generally useful for OpenStack development, but if you have other requirements, or just don't like to have empty open ports you can define them in your Envyfile

To add custom security groups you can put define them in your Envyfile following the format below:

  sec_groups: [
    'icmp, -1, -1, 0.0.0.0/0',
    'tcp, 22, 22, 0.0.0.0/0',
    'tcp, 80, 80, 0.0.0.0/0',
    'tcp, 3000, 3000, 0.0.0.0/0'
  ]

Useful patterns for provision scripts

There are a number of common parameters that need to be configured on a per-instance basis during provisioning, many of which aren't obviously available. However, much of this data can be obtained from the cloud metadata service (a concept originated by Amazon's EC2 and extended by OpenStack). The metadata service is a RESTful web service which lives at a known IP address (169.254.169.254) which is routable from each instance in the cloud.

Here are some commonly needed pieces of data and the corresponding bash code to get them from the core metadata service:

Instance UUID:

curl http://169.254.169.254/openstack/latest/meta_data.json | python -c 'import sys, json; print json.load(sys.stdin)["uuid"]'

Instance Name:

curl http://169.254.169.254/openstack/latest/meta_data.json | python -c 'import sys, json; print json.load(sys.stdin)["name"]'

Fixed IP:

curl http://169.254.169.254/latest/meta-data/local-ipv4

Floating IP:

curl http://169.254.169.254/latest/meta-data/public-ipv4

The user-defined server metadata is also available via an OpenStack extension to the metadata service which returns a JSON blob:

OpenStack Auth URL (added to server metadata by CloudEnvy):

curl http://169.254.169.254/openstack/latest/meta_data.json | python -c 'import sys, json; print json.load(sys.stdin)["meta"]["os_auth_url"]'

Arbitrary Instance Metadata Values (be sure to specify the key you want):

curl http://169.254.169.254/openstack/latest/meta_data.json | python -c 'import sys, json; print json.load(sys.stdin)["meta"][sys.argv[1]]' <your key here>

Name of first public key:

curl http://169.254.169.254/openstack/latest/meta_data.json | python -c 'import sys, json; print json.load(sys.stdin)["public_keys"].keys()[0]'

cloudenvy's People

Contributors

arthurzenika avatar bcwaldon avatar flaper87 avatar flepied avatar gabrielhurley avatar hartzell avatar heckj avatar ipl31 avatar issackelly avatar jakedahn avatar jfriedly avatar mbascus avatar mgius avatar mszilagyi avatar pabelanger avatar sleepsonthefloor avatar termie avatar vishvananda avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cloudenvy's Issues

Figure out strategy for multi-node deployments

This is going to be a tricky one, so I'm pushing it out to v0.5.0 milestone.

There are a few options for this.

  1. Simple system which launches n number of instances, waits till they're all assigned a floating ips, then run parameterized provision scripts on each node. By parameterized I mean all of the provision scripts would need to be able to take an argument of the IP.
  2. Complex system which supports something like Ansible. This is where I'm leaning currently because it will allow for a better and more maintainable approach to multi-node deployment. This could also be written in a way that people could write a driver of sorts to support silly things like chef or puppet.
  3. ?? suggestions plz!

Optional not quite optional

(at least in the pip version) I found that:

remote_user
flavor_name

were not optional. This might have been fixed, and/or my memory might have been faulty.

'envy up' with image that does not exist prints ugly traceback

% envy -c vagrant up
Traceback (most recent call last):
File "/Users/bcwaldon/src/cloudenvy/.venv/bin/envy", line 8, in
load_entry_point('cloudenvy==0.2.2', 'console_scripts', 'envy')()
File "/Users/bcwaldon/src/cloudenvy/cloudenvy/main.py", line 73, in main
args.func(config, args)
File "/Users/bcwaldon/src/cloudenvy/cloudenvy/commands/envy_up.py", line 32, in run
envy.build_server()
File "/Users/bcwaldon/src/cloudenvy/cloudenvy/envy.py", line 66, in build_server
image = self.cloud_api.find_image(image_name)
File "/Users/bcwaldon/src/cloudenvy/cloudenvy/cloud.py", line 29, in wrapped
return func(_args, *_kwargs)
File "/Users/bcwaldon/src/cloudenvy/cloudenvy/cloud.py", line 14, in wrapped
return func(_args, *_kwargs)
File "/Users/bcwaldon/src/cloudenvy/cloudenvy/cloud.py", line 112, in find_image
image = self.client.images.get(search_str)
File "/Users/bcwaldon/src/cloudenvy/.venv/lib/python2.7/site-packages/python_novaclient-2.9.0-py2.7.egg/novaclient/v1_1/images.py", line 38, in get
return self._get("/images/%s" % base.getid(image), "image")
File "/Users/bcwaldon/src/cloudenvy/.venv/lib/python2.7/site-packages/python_novaclient-2.9.0-py2.7.egg/novaclient/base.py", line 142, in _get
return self.resource_class(self, body[response_key], loaded=True)
TypeError: string indices must be integers, not str

Need a way to copy files as part of provisioning process.

Simply being able to copy over and run scripts via provision_scripts is nice, but it would be even better if it were possible to copy over files, too, via config entries in Envyfile.yml. For example, I want to copy over a Puppet manifest and run it as root. My solution right now is a giant "here" document:

#!/bin/sh

cat > manifest.pp <<EOF
...puppet puppet puppet...
EOF

sudo puppet apply manifest.pp

This works, but it's really ugly. I would rather be able to do something like:

provision_files:
- resources/manifest.pp
provision_scripts:
- apply_manifest.sh

In fact, this ought to be able to copy over entire directories recursively.

Cannot find sudo when putting a file on a debian machine

$ envy files
[[email protected]] put: file.ext -> /tmp/file.ext

Fatal error: sudo() received nonzero return code 127 while executing!

Requested: chmod 664 "b3718da59d2d33e074c2ab6242c9656c345d9a9e"
Executed: sudo -S -p 'sudo password:'  /bin/bash -l -c "chmod 664 \"b3718da59d2d33e074c2ab6242c9656c345d9a9e\""

======================================================================= Standard output =======================================================================

bash: sudo: command not found

===============================================================================================================================================================

Aborting.

Maybe use_sudo=True in commands/files.py should be optional or catch the error and try with use_sudo=False (hotfixing works).

Improve snapshot UX

The usability of 'envy snapshot' is a bit wonky. I'd love to be able to do the following: 'envy up; envy snapshot; envy restore'. Creating a 'restore' action might be the solution here.

License?!

I can't use this code because you haven't licensed me to do so!

Feature Request: Ability to source a different Envyfile

We have two different ways to provision a project that we would like to use Cloudenvy for. Unfortunately it only allows one Envyfile. It should be nice to be able to tell it to use a different one via the command line arguments so that you can have a project launched in various ways via the project_config.

I suppose another way to allow this would be to have multiple project_config sections in the Envyfile...

return codes

Cloudenvy should be a good unix citizen and return non-zero error codes in the case of failure.

Allow user-defined server metadata

The user-defined server metadata is quite useful for both management overhead and simplifying config/provisioning of instances. It should be possible to define arbitrary key value pairs that will be added to the server at launch time. These values should also be templatable so that known local variables (such as the cloud's auth URL) can be inserted at runtime.

fabric error when running a provision script

while doing a "envy provision", the remote script did a "git clone..."

Envy errored in this process:

[10.129.16.59] out: Warning: Permanently added 'github.com,207.97.227.239' (RSA) to the list of known hosts.
Exception in thread Thread-2:
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 552, in __bootstrap_inner
self.run()
File "/usr/local/lib/python2.7/dist-packages/ssh/agent.py", line 115, in run
self._communicate()
File "/usr/local/lib/python2.7/dist-packages/ssh/agent.py", line 125, in _communicate
events = select([self._agent._conn, self.__inr], [], [], 0.5)
TypeError: argument must be an int, or have a fileno() method.

I hit Control-C to kill it out:

Traceback (most recent call last):
File "/usr/local/bin/envy", line 9, in
load_entry_point('cloudenvy==0.1.0', 'console_scripts', 'envy')()
File "/usr/local/lib/python2.7/dist-packages/cloudenvy/main.py", line 389, in main
args.func(args)
File "/usr/local/lib/python2.7/dist-packages/cloudenvy/main.py", line 185, in envy_provision
fabric.operations.run(remote_provision_script_path)
File "/usr/local/lib/python2.7/dist-packages/fabric/network.py", line 463, in host_prompting_wrapper
return func(_args, *_kwargs)
File "/usr/local/lib/python2.7/dist-packages/fabric/operations.py", line 909, in run
return _run_command(command, shell, pty, combine_stderr)
File "/usr/local/lib/python2.7/dist-packages/fabric/operations.py", line 820, in _run_command
combine_stderr)
File "/usr/local/lib/python2.7/dist-packages/fabric/operations.py", line 733, in _execute
time.sleep(ssh.io_sleep)
KeyboardInterrupt

Specify default cloud for an Envyfile

I can specify a cloud in the CLI, or it will take some based on how it serializes, iterates, and take the first one it finds, I would like to say "this envy file defaults to cloud foo"

Possibly this is contrary to design decisions already made about cross-compatability for different users or naming schemes.

Enable a specification of a network to use when multiple networks are available (openstack icehouse)

Envy works great on our essex install of openstack which we're trying to replace by an icehouse version. Am having problems using it with icehouse though

$ envy -v up
INFO:root:Triggering Envy boot.
INFO:root:Using image: debian-wheezy-x86_64
INFO:root:Using security group: ckan-test
INFO:root:Creating Security Group Rule ('icmp', '-1', '-1', '0.0.0.0/0')
INFO:root:Security Group Rule "('icmp', '-1', '-1', '0.0.0.0/0')" already exists.
INFO:root:Creating Security Group Rule ('tcp', '22', '22', '0.0.0.0/0')
INFO:root:Security Group Rule "('tcp', '22', '22', '0.0.0.0/0')" already exists.
INFO:root:Creating Security Group Rule ('tcp', '80', '80', '0.0.0.0/0')
INFO:root:Security Group Rule "('tcp', '80', '80', '0.0.0.0/0')" already exists.
INFO:root:Creating Security Group Rule ('tcp', '443', '443', '0.0.0.0/0')
INFO:root:Security Group Rule "('tcp', '443', '443', '0.0.0.0/0')" already exists.
INFO:root:Creating Security Group Rule ('tcp', '8000', '8000', '0.0.0.0/0')
INFO:root:Security Group Rule "('tcp', '8000', '8000', '0.0.0.0/0')" already exists.
INFO:root:Creating Security Group Rule ('tcp', '8001', '8001', '0.0.0.0/0')
INFO:root:Security Group Rule "('tcp', '8001', '8001', '0.0.0.0/0')" already exists.
INFO:root:Creating Security Group Rule ('tcp', '8080', '8080', '0.0.0.0/0')
INFO:root:Security Group Rule "('tcp', '8080', '8080', '0.0.0.0/0')" already exists.
INFO:root:...done.
INFO:root:Using keypair: arthur
INFO:root:Creating server...
ERROR:root:Unable to communicate with endpoints: Received 400/Bad Request from OpenStack: Multiple possible networks found, use a Network ID to be more specific. (HTTP 400) (Request-ID: req-df7643d5-fffa-40a4-8300-f0fa8b061bbe)

Did I miss a configuration option to specify an id or a name for the network to use or does this need to be implemented ?

(thanks for cloudenvy, it's awesome)

envy config(?) command

Implement an envy command to create a .cloudenvy config in the current directory. Optionally, prompt for inputs to populate settings during creation.

dotfiles ignores files that are symbolic links

I found out the hard way that "envy dotiles" ignores .dotfiles that are symbolic links (which mine are, since I link them from a git repo). I would like/prefer envy dotfiles to get the actual files and drop them into the target machine based on config.

Optionally run script as root?

Most of my provisioning scripts need to do something as root in order to change the configuration of the target system. It would be nice if my Envyfile could have something like...

provision_scripts_root:
- myscript.sh

...and then have cloudenvy automatically run these as root (via sudo?) on the remote host.

Envy VNC

Having envy vnc would be useful for diagnostic purposes, or any scenario where you have a real gui that needs to be interacted with.

Leaky pipes

I am running into an issue while running envy up with 5-6 provision scripts. The entirety of the run takes about 30 minutes. During the course of the run, the file descriptor usage grows significantly. It looks like pipes are not getting closed correctly:

envy 12157 kevin.tegtmeier 505r FIFO 0,8 0t0 20247361 pipe
envy 12157 kevin.tegtmeier 506w FIFO 0,8 0t0 20247361 pipe
envy 12157 kevin.tegtmeier 507u unix 0x0000000000000000 0t0 20250672 socket

(I have about 800 of these open pipes and sockets)

I can repro on OS X and Ubuntu 12.04. I can get more info on versions of everything, but I've talked with several devs that are hitting this on different boxes with different versions of python, envy, etc so probably should be very easy to repro on your end.

Refactor to work on multiple cloud providers

This is going to be fairly tricky to do since cloudenvy right now is so openstack specific. It is going to require some pretty major refactoring to complete.

What I would like to do is figure out a way to abstract the cloud api to something super generic which can be used for most/all cloud providers. And allow people to implement their own cloud drivers.

I think the best approach to this is going to be to look at how https://github.com/apache/libcloud approaches this. Ideally our cloud layer would just be libcloud itself, but I'm not really sure how that would effect some of the command components.

Have a way of putting files in non-existing directories

When trying to put a file into /tmp/doesntexist/file.ext I get the following error

 Fatal error: put() encountered an exception while uploading 'file.ext'

Underlying exception:
    No such file

Aborting.

I can't create /tmp/doesntexist/ in provision scripts since they run after "files".

A quick read of the fabric documentation doesn't seem to offer this possibility.

Could this be added to files.py ?

My current workaround is to copy the files in /tmp/ then doing the mkdir and move in the provision scripts, but this is not ideal.

%s in "error" message not getting filled in

While "envy up" and waiting for the instance to get spawned, I see this "error message" with the embedded %s -

should probably be a WARN or INFO, and the %s need to be removed or filled in appropriately.

ERROR:root:Unable to upload the provision script from %s. Your ENVy is probably still booting. Trying again in 10 seconds.

Need Volume Support

Suggested Config

volumes:
    <name>:
         size: [human readable size, or just (int)<gigs>]
         mount_point: /foo/bar
         fs: ext3

Send floating IP as remote environment variable

It's very common for provision scripts to need the external (e.g.floating) IP address of the VM. Since the VM is not aware of that address (it's not in the interface list, etc.) there's no way to get that information currently without prompting the user for it.

Instead, since envy uses novaclient to get the floating IP on the client side, it could use fabric's ability to set remote environment variables to send the floating IP across, making it available to the provision script, etc.

Envy Files timeout is too long

240 seconds per failure, and you will probably have many failures (if you have any), and it will possibly leave your system in an incosistent state (will have uploaded some files, appeared to pass, but will not have.

I'll write a patch, I just wanted to file an issue while I'm thinking about it.

traceback, not useful error, when DNS is broken

I live in a painful world of partially working DNS. When it's down and dead, I'm screwed. I'll live with that, but I'd prefer to get a useful message from envy instead of the following traceback:

(envy)$ envy list
Traceback (most recent call last):
File "/usr/local/bin/envy", line 8, in
load_entry_point('cloudenvy==0.1.0', 'console_scripts', 'envy')()
File "/Library/Python/2.7/site-packages/cloudenvy/main.py", line 389, in main
args.func(args)
File "/Library/Python/2.7/site-packages/cloudenvy/main.py", line 105, in envy_list
foo = envy.list_servers()
File "/Library/Python/2.7/site-packages/cloudenvy/envy.py", line 35, in list_servers
return self.cloud_api.list_servers()
File "/Library/Python/2.7/site-packages/cloudenvy/cloud.py", line 46, in list_servers
return self.client.servers.list()
File "/Library/Python/2.7/site-packages/novaclient/v1_1/servers.py", line 309, in list
return self._list("/servers%s%s" % (detail, query_string), "servers")
File "/Library/Python/2.7/site-packages/novaclient/base.py", line 62, in _list
_resp, body = self.api.client.get(url)
File "/Library/Python/2.7/site-packages/novaclient/client.py", line 239, in get
return self._cs_request(url, 'GET', *_kwargs)
File "/Library/Python/2.7/site-packages/novaclient/client.py", line 215, in _cs_request
self.authenticate()
File "/Library/Python/2.7/site-packages/novaclient/client.py", line 360, in authenticate
auth_url = self._v2_auth(auth_url)
File "/Library/Python/2.7/site-packages/novaclient/client.py", line 438, in _v2_auth
self._authenticate(url, body)
File "/Library/Python/2.7/site-packages/novaclient/client.py", line 449, in _authenticate
resp, body = self._time_request(token_url, "POST", body=body)
File "/Library/Python/2.7/site-packages/novaclient/client.py", line 208, in _time_request
resp, body = self.request(url, method, *_kwargs)
File "/Library/Python/2.7/site-packages/novaclient/client.py", line 202, in request
raise exceptions.from_response(resp, body)
novaclient.exceptions.BadRequest: n/a (HTTP 400)

"envy ssh" should accept arguments

I thought maybe I could write something like this:

envy ssh somecommand

But that just results in:

usage: envy [-h] [-v] [-c CLOUD]
        {up,list,provision,snapshot,ip,scp,dotfiles,ssh,destroy,run,help}
        ...
envy: error: unrecognized arguments: somecommand

It would be nice if envy ssh was a more generic wrapper for the ssh command.

Rate Limiting of Security Group Requests

If you have a lot of security group rules to add, it can be rate-limited by the novaclient, here is my specific error:

01:50:27PM ~/Documents/workspace/project: envy -v up
INFO:root:Triggering ENVy boot.
INFO:root:Using image: Ubuntu 12.04 cloudimg amd64
INFO:root:Using security group: mygroup
INFO:root:Creating Security Group Rule ('icmp', '-1', '-1', '0.0.0.0/0')
INFO:root:Security Group Rule "('icmp', '-1', '-1', '0.0.0.0/0')" already exists.
INFO:root:Creating Security Group Rule ('tcp', '22', '22', '0.0.0.0/0')
INFO:root:Security Group Rule "('tcp', '22', '22', '0.0.0.0/0')" already exists.
INFO:root:Creating Security Group Rule ('tcp', '80', '80', '0.0.0.0/0')
INFO:root:Security Group Rule "('tcp', '80', '80', '0.0.0.0/0')" already exists.
INFO:root:Creating Security Group Rule ('tcp', '3000', '3000', '0.0.0.0/0')
INFO:root:Security Group Rule "('tcp', '3000', '3000', '0.0.0.0/0')" already exists.
INFO:root:Creating Security Group Rule ('tcp', '5000', '5000', '0.0.0.0/0')
INFO:root:Security Group Rule "('tcp', '5000', '5000', '0.0.0.0/0')" already exists.
INFO:root:Creating Security Group Rule ('tcp', '8774', '8774', '0.0.0.0/0')
INFO:root:Security Group Rule "('tcp', '8774', '8774', '0.0.0.0/0')" already exists.
INFO:root:Creating Security Group Rule ('tcp', '35357', '35357', '0.0.0.0/0')
INFO:root:Security Group Rule "('tcp', '35357', '35357', '0.0.0.0/0')" already exists.
INFO:root:Creating Security Group Rule ('tcp', '137', '139', '0.0.0.0/0')
INFO:root:Security Group Rule "('tcp', '137', '139', '0.0.0.0/0')" already exists.
INFO:root:Creating Security Group Rule ('tcp', '445', '445', '0.0.0.0/0')
INFO:root:Security Group Rule "('tcp', '445', '445', '0.0.0.0/0')" already exists.
INFO:root:Creating Security Group Rule ('tcp', '389', '389', '0.0.0.0/0')
INFO:root:Security Group Rule "('tcp', '389', '389', '0.0.0.0/0')" already exists.
INFO:root:Creating Security Group Rule ('tcp', '901', '901', '0.0.0.0/0')
Traceback (most recent call last):
  File "/usr/local/bin/envy", line 8, in <module>
    load_entry_point('cloudenvy==0.3.1', 'console_scripts', 'envy')()
  File "/Library/Python/2.7/site-packages/cloudenvy/main.py", line 71, in main
    args.func(config, args)
  File "/Library/Python/2.7/site-packages/cloudenvy/commands/envy_up.py", line 34, in run
    envy.build_server()
  File "/Library/Python/2.7/site-packages/cloudenvy/envy.py", line 95, in build_server
    self._ensure_sec_group_exists(self.sec_group_name)
  File "/Library/Python/2.7/site-packages/cloudenvy/envy.py", line 167, in _ensure_sec_group_exists
    self.cloud_api.create_security_group_rule(sec_group, rule)
  File "/Library/Python/2.7/site-packages/cloudenvy/cloud.py", line 154, in create_security_group_rule
    security_group.id, *rule)
  File "/Library/Python/2.7/site-packages/novaclient/v1_1/security_group_rules.py", line 55, in create
    'security_group_rule')
  File "/Library/Python/2.7/site-packages/novaclient/base.py", line 148, in _create
    _resp, body = self.api.client.post(url, body=body)
  File "/Library/Python/2.7/site-packages/novaclient/client.py", line 244, in post
    return self._cs_request(url, 'POST', **kwargs)
  File "/Library/Python/2.7/site-packages/novaclient/client.py", line 228, in _cs_request
    **kwargs)
  File "/Library/Python/2.7/site-packages/novaclient/client.py", line 210, in _time_request
    resp, body = self.request(url, method, **kwargs)
  File "/Library/Python/2.7/site-packages/novaclient/client.py", line 204, in request
    raise exceptions.from_response(resp, body)
novaclient.exceptions.OverLimit: This request was rate-limited. (HTTP 413)

Some "INFO" Messages When Using -v Should Be "DEBUG"

The one in particular I am seeing is:

INFO:requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): 12.12.12.12

It gets REALLY noisy... Maybe not show these connection messages with -v, or have another flag to set for debug messages.

Fails to provision even when provision file is set and correctly uploaded to VM

$ envy up

Fatal error: run() received nonzero return code 2 while executing!

Requested: ~/provision.sh
Executed: /bin/bash -l -c "~/provision.sh"

Aborting.
You have not specified any provision scripts in your Envyfile. If you would like to run your ENVy without a provision script; use the `--no-provision` command line flag.

How do I debug this ?

Doing a separate call ("envy up --no-provision" then "envy provision") works.

envy down

Seems like destroy is the wrong verb. up/down or create/destroy feels better.

It's not my bikeshed to paint, just want to bring it up.

The "image:" property in the "project_config:" section of the Envyfile needs work...

If I have multiple clouds configured in my ~/.cloudenvy file, sometimes they have the same image, but with differing names...

This makes it difficult to have a project configured to use an image, when that image name exists on all but, say, one of my clouds... It might be nice to have image be a property of the ~/.cloudenvy file under each cloud, and then the ability to select which image to use (if multiple are supplied for a cloud) when using envy -c myCloud4 up

Let me know if this problem makes sense or not, I'm not sure I am describing the issue very well...

traceback on ratelimit through API

When using cloudenvy and the API returns a 413 RateLimit exception from the novaclient, Envy throws a traceback and dies.

$ envy up
Traceback (most recent call last):
File "/usr/local/bin/envy", line 9, in
load_entry_point('cloudenvy==0.1.0', 'console_scripts', 'envy')()
File "/home/heckj/src/cloudenvy/cloudenvy/main.py", line 389, in main
args.func(args)
File "/home/heckj/src/cloudenvy/cloudenvy/main.py", line 127, in envy_up
envy.build_server()
File "/home/heckj/src/cloudenvy/cloudenvy/envy.py", line 105, in build_server
self.cloud_api.assign_ip(server, ip)
File "/home/heckj/src/cloudenvy/cloudenvy/cloud.py", line 73, in assign_ip
server.add_floating_ip(ip)
File "/usr/local/lib/python2.7/dist-packages/novaclient/v1_1/servers.py", line 82, in add_floating_ip
self.manager.add_floating_ip(self, address)
File "/usr/local/lib/python2.7/dist-packages/novaclient/v1_1/servers.py", line 338, in add_floating_ip
self._action('addFloatingIp', server, {'address': address})
File "/usr/local/lib/python2.7/dist-packages/novaclient/v1_1/servers.py", line 689, in _action
return self.api.client.post(url, body=body)
File "/usr/local/lib/python2.7/dist-packages/novaclient/client.py", line 243, in post
return self._cs_request(url, 'POST', *_kwargs)
File "/usr/local/lib/python2.7/dist-packages/novaclient/client.py", line 227, in _cs_request
*_kwargs)
File "/usr/local/lib/python2.7/dist-packages/novaclient/client.py", line 209, in _time_request
resp, body = self.request(url, method, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/novaclient/client.py", line 203, in request
raise exceptions.from_response(resp, body)
novaclient.exceptions.OverLimit: This request was rate-limited. (HTTP 413)

global name 'exceptions' is not defined

Traceback (most recent call last):
File "/usr/local/bin/envy", line 8, in
load_entry_point('cloudenvy==0.0.2', 'console_scripts', 'envy')()
File "/Users/anthonyyoung/code/cloudenvy/cloudenvy/main.py", line 212, in main
args.func(args)
File "/Users/anthonyyoung/code/cloudenvy/cloudenvy/main.py", line 95, in up
env.build_server()
File "/Users/anthonyyoung/code/cloudenvy/cloudenvy/template.py", line 91, in build_server
ip = self.cloud_api.find_free_ip()
File "/Users/anthonyyoung/code/cloudenvy/cloudenvy/cloud.py", line 61, in find_free_ip
raise exceptions.NoIPsAvailable()
NameError: global name 'exceptions' is not defined

Odd output on failed provision script

If you 'envy up' with a provision script (defined in Envyfile) that fails, you will see the following cloudenvy output:

You have not specified any provision scripts in your Envyfile. If you would like to run your ENVy without a provision script; use the --no-provision command line flag.

This isn't quite true - a provision script was defined yet it failed. We should correct this output.

unnecessary ERROR output

This output is ugly and misleading, yet it doesn't indicate a sure failure. I'd be interested in making this DEBUG level vs ERROR level:

% envy up
[10.129.16.56] run: if [ -e "$HOME/setup_env.sh" ]; then rm ~/setup_env.sh; fi
ERROR:root:Unable to upload the provision script from %s. Your ENVy is probably still booting. Trying again in 10 seconds.
[10.129.16.56] run: if [ -e "$HOME/setup_env.sh" ]; then rm ~/setup_env.sh; fi
ERROR:root:Unable to upload the provision script from %s. Your ENVy is probably still booting. Trying again in 10 seconds.
[10.129.16.56] run: if [ -e "$HOME/setup_env.sh" ]; then rm ~/setup_env.sh; fi
ERROR:root:Unable to upload the provision script from %s. Your ENVy is probably still booting. Trying again in 10 seconds.
[10.129.16.56] run: if [ -e "$HOME/setup_env.sh" ]; then rm ~/setup_env.sh; fi
ERROR:root:Unable to upload the provision script from %s. Your ENVy is probably still booting. Trying again in 10 seconds.
[10.129.16.56] run: if [ -e "$HOME/setup_env.sh" ]; then rm ~/setup_env.sh; fi
ERROR:root:Unable to upload the provision script from %s. Your ENVy is probably still booting. Trying again in 10 seconds.
[10.129.16.56] run: if [ -e "$HOME/setup_env.sh" ]; then rm ~/setup_env.sh; fi
ERROR:root:Unable to upload the provision script from %s. Your ENVy is probably still booting. Trying again in 10 seconds.
[10.129.16.56] run: if [ -e "$HOME/setup_env.sh" ]; then rm ~/setup_env.sh; fi
ERROR:root:Unable to upload the provision script from %s. Your ENVy is probably still booting. Trying again in 10 seconds.

envy up fails to provision files

Doing $ envy -v up

Does (I control-C after a while

INFO:root:Copying file from 'iptables' to '~'
INFO:paramiko.transport:Connected (version 2.0, client OpenSSH_5.3)
INFO:paramiko.transport:Connected (version 2.0, client OpenSSH_5.3)
INFO:paramiko.transport:Connected (version 2.0, client OpenSSH_5.3)
[snip]
^CTraceback (most recent call last):
  File "/home/arthur/.virtualenvs/cloudenvy/bin/envy", line 9, in <module>
    load_entry_point('cloudenvy==0.8.0', 'console_scripts', 'envy')()
  File "/home/arthur/.virtualenvs/cloudenvy/local/lib/python2.7/site-packages/cloudenvy/main.py", line 94, in main
    args.func(config, args)
  File "/home/arthur/.virtualenvs/cloudenvy/local/lib/python2.7/site-packages/cloudenvy/commands/up.py", line 41, in run
    self.commands['files'].run(config, args)
  File "/home/arthur/.virtualenvs/cloudenvy/local/lib/python2.7/site-packages/cloudenvy/commands/files.py", line 45, in run
    self._put_file(local_path, remote_path, use_sudo)
  File "/home/arthur/.virtualenvs/cloudenvy/local/lib/python2.7/site-packages/cloudenvy/commands/files.py", line 65, in _put_file
    use_sudo=use_sudo)
  File "/home/arthur/.virtualenvs/cloudenvy/local/lib/python2.7/site-packages/fabric/network.py", line 639, in host_prompting_wrapper
    return func(*args, **kwargs)
  File "/home/arthur/.virtualenvs/cloudenvy/local/lib/python2.7/site-packages/fabric/operations.py", line 346, in put
    ftp = SFTP(env.host_string)
  File "/home/arthur/.virtualenvs/cloudenvy/local/lib/python2.7/site-packages/fabric/sftp.py", line 30, in __init__
    self.ftp = connections[host_string].open_sftp()
  File "/home/arthur/.virtualenvs/cloudenvy/local/lib/python2.7/site-packages/fabric/network.py", line 151, in __getitem__
    self.connect(key)
  File "/home/arthur/.virtualenvs/cloudenvy/local/lib/python2.7/site-packages/fabric/network.py", line 143, in connect
    self[key] = connect(user, host, port, cache=self)
  File "/home/arthur/.virtualenvs/cloudenvy/local/lib/python2.7/site-packages/fabric/network.py", line 407, in connect
    client.load_system_host_keys()
  File "/home/arthur/.virtualenvs/cloudenvy/local/lib/python2.7/site-packages/paramiko/client.py", line 152, in load_system_host_keys
    self._system_host_keys.load(filename)
  File "/home/arthur/.virtualenvs/cloudenvy/local/lib/python2.7/site-packages/paramiko/hostkeys.py", line 176, in load
    e = HostKeyEntry.from_line(line, lineno)
  File "/home/arthur/.virtualenvs/cloudenvy/local/lib/python2.7/site-packages/paramiko/hostkeys.py", line 86, in from_line
    key = ECDSAKey(data=base64.decodestring(key))
  File "/home/arthur/.virtualenvs/cloudenvy/local/lib/python2.7/site-packages/paramiko/ecdsakey.py", line 70, in __init__
    curve=curves.NIST256p)
  File "/home/arthur/.virtualenvs/cloudenvy/local/lib/python2.7/site-packages/ecdsa/keys.py", line 43, in from_string
    assert ecdsa.point_is_valid(curve.generator, x, y)
  File "/home/arthur/.virtualenvs/cloudenvy/local/lib/python2.7/site-packages/ecdsa/ecdsa.py", line 201, in point_is_valid
    if not n*ellipticcurve.Point( curve, x, y ) == \
  File "/home/arthur/.virtualenvs/cloudenvy/local/lib/python2.7/site-packages/ecdsa/ellipticcurve.py", line 143, in __rmul__
    return self * other
  File "/home/arthur/.virtualenvs/cloudenvy/local/lib/python2.7/site-packages/ecdsa/ellipticcurve.py", line 132, in __mul__
    result = result.double()
  File "/home/arthur/.virtualenvs/cloudenvy/local/lib/python2.7/site-packages/ecdsa/ellipticcurve.py", line 161, in double
    numbertheory.inverse_mod( 2 * self.__y, p ) ) % p
  File "/home/arthur/.virtualenvs/cloudenvy/local/lib/python2.7/site-packages/ecdsa/numbertheory.py", line 197, in inverse_mod
    uc, vc, ud, vd = ud - q*uc, vd - q*vc, uc, vc
KeyboardInterrupt

Any idea what is going wrong ? envy files does the same, envy provision works though.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.