0

Im writing a program which automatically creates servers in openstack when needed. The problem is that I want the program to wait until the instance has gotten its ip address before proceeding. If the instance has not gotten its ip, novaclient will throw an exception and the object will die. Using the sleep function makes it work, but I dont want that to be the permanent solution.

   ipAddress = None
   try:
        instance = nova.servers.create(name=self.hostName, image=image,
                                flavor=flavor, key_name="mykey",
                                nics=nics)
        while(ipAddress == None): #<---Something like this, just actually working
            for network in instance.networks['my_net']:
                if re.match('\d+\.\d+\.\d+\.\d+', network):
                    self.ipAddress = network
                    break

        print 'The server is waiting at IP address {0}.'.format(self.ipAddress)

    except:
        print "could not create webserver"
        #WebManager.exception(hostname)

    finally:
        print("Execution Completed")
        self.addToLoadbalancer()

Is there a way to write a sort of spinlock or similar that will wait unntil the server have gotten its ip? Any tips would be great.

Leafbreaker
  • 93
  • 1
  • 7
  • What you've written already _is_ a spinlock. It spins as fast as possible, checking repeatedly, until its condition is true. This is a bad idea for the same reason spinlocks are usually a bad idea in user code and/or for waits that are likely to take a non-trivial amount of time. – abarnert May 06 '15 at 03:03
  • Using `sleep` to make a microsleeping spinlock (check every 100ms instead of as fast as possible, or just `sleep(0)` each time) is an improvement; I don't know why you don't want that. – abarnert May 06 '15 at 03:05
  • Finally, the _right_ answer here is obviously to for your script to be notified in some way. But if there are no notifications from Openstack or the OS or whatever, and you can't fix that, then you don't really have a choice. – abarnert May 06 '15 at 03:06
  • I know, but this spinlock does not work since the program will crash due to that the instance does not have 'my_net', thus no ip before roughly 20 seconds. I dont know if its possible for python to ignore such an exception and just carry on. – Leafbreaker May 06 '15 at 03:08
  • One last thing: You almost never want to compare `while spam == None:`. You either mean `while spam is None:` (if you want anything other than `None` to be acceptable), or `while not spam:` (if you only want something truthy to be acceptable). The only time you'd ever use `== None` is if you'd built some weird class that compares equal to `None`. – abarnert May 06 '15 at 03:08
  • Ok thanks for your feedback, Now I at least now that there is no straight forward 'magic command'. Thanks abarnert. ^^ – Leafbreaker May 06 '15 at 03:09
  • OK, if the problem is that `instance.networks` exists, but `instance.networks['my_net']` doesn't, then you can just spin on `while 'my_net' not in instance.networks:`. But again, I think you want to sleep repeatedly within that loop, not actually busy-wait. – abarnert May 06 '15 at 03:10
  • Sweet I will try that. and adding some sleep time is probably smart, so I dont spam-lock. Thanks again – Leafbreaker May 06 '15 at 03:13
  • I just noticed that 20 seconds. Yeah, I'd sleep for something like 250ms at a time between checks; no point wasting lots of CPU, especially at server startup time, when probably dozens of other threads are probably begging for CPU time… But meanwhile, are you sure there's no notification you can get from the novaclient object, instead of spinning at all? – abarnert May 06 '15 at 03:19
  • I found that there is a way to find in what state the machine is in. by using isntance.status. The result is initially 'BUILD' and its ready when its status is 'ACTIVE'. The weird part is the status wont change now, even though the machine is up and running. (Can see status in the web GUI as well) It just keeps spinning – Leafbreaker May 06 '15 at 04:16

1 Answers1

0

I managed to fix the issue. It turned out it was hard to detect when the machine was ready by using only novaclient. By using nova list I managed to get the ip address.

while 1 == 1:
    result = getbash("nova list" + " | grep " + hostname + \\
             " | awk '{print $12}'").split('=')
    if re.match('\d+\.\d+\.\d+\.\d+', result[-1]):
        self.ipAddress = result[-1]
        print 'The server is waiting at IP address {0}.'.format(self.ipAddress)
        break
    sleep(1)

This code queries for the hostname and checks if the instance has recieved an ip address. The getbash() function is a simple subprocess function which return the output of subprocess.Popen(command,stdout=subprocess.PIPE, shell=True)

Leafbreaker
  • 93
  • 1
  • 7