PyConAu - Day Two
Posted by Craige McWhirter on

Keynote: Consequences of an Insightful Algorithm

by Carina C. Zona

Carina gave a fantastic talk of the very real consequences of our interactions with data mining and the algorithms used to target us. A must watch when the video comes out.

Update: Video is now available here. Slides are over there.

Adventures in pip land

by Robert Collins

A humorous and contructive talk on the pitfalls of pip. Strongly recommended that people no longer use it.

Arrested Development - surviving the awkward adolescence of a microservices-based application

By Scott Triglia

  • Logging is a super power.
  • Be explicit
  • Measure everything
  • Scale via automation

Rapid prototyping with teenagers

by Katie Bell

  • Run coding camps and competitions for kids with no prior experience required.
  • Courses and competitions designed to bootstrap kids into programming basics.

Test-Driven Repair

by Christopher Neugebauer

  • Bad tests are better than no tests.
  • Write tests early.
  • Results in better interfaces.
  • Clearer separation.
  • Write tests first.
  • An interface is anything that gives OK isolation to the code you want to test.
  • Good interfaces tests will test very branch.
  • Measure all the things.
  • Measure setup time
  • Measure execution time
  • Run tests thoroughly nightly.
  • Make it easy to translate a bug report into a test case.
  • Retain your test cases and run them regularly.

Playing to lose: making sensible security decisions by assuming the worst

by Tom Eastman

  • Minimise the attack surface.
  • Reduce the privileges of the account used by the app.
  • Eliminate SQL injections.
  • White list input validation.
  • "Escape" all data appropriately.
  • Use Content Security Policy to protect against cross site scripting.
  • Don't have all your eggs in one basket.
  • You can always have better logging. Off site logging is useful.
  • Take a look at the ELK stack.

PyConAu - Day One
Posted by Craige McWhirter on

Keynote: Designed for education: a Python solution

by Carrie Anne Philbin

Excellent keynote on using Python in education. Many interesting insights into what's being done well, what needs improving and how to contribute.

Slow Down, Compose Yourself - How Composition Can Help You Write Modular, Testable Code

by Amber "Hawkie" Brown

  • Modularity and testability traits are desirable.
  • Tests are the only way ti ensure your code works
  • When designing a system, plan for these traits
  • Fake components can be used to return hard to replicate conditions ie: a database returning "no more space"
  • Ensure you have correctness at every level.
  • Suggests using practices from better (functional programming) languages like Haskell with Python.

Tales from Managing an Open Source Python Game

by Josh Bartlett

  • Trosnoth is a 2D side scrolling game.
  • Team strategy game
  • Involve people at every step of the process.
  • Have a core group of interested people and allow them to contribute and become involved to increase commitment.
  • Build community.
  • Get people excited
  • Be prepared to be wrong.
  • Encourage people to be involved.
  • Start with "good enough".
  • Re-writing everything blocked contributions for the period of the re-write.
  • Look for ideas anywhere.
  • Mistakes are a valuable learning opportunity.
  • Your people and your community are what makes the project work.

Ansible, Simplicity, and the Zen of Python

by Todd Owen (http://2015.pycon-au.org/schedule/30057/view_talk?day=saturday)

  • Ansible is a push model of configuration management and automation.
  • Pull model of Chef and Puppet is unnecessarily complex.
  • Ansible's simplicity is a great asset
  • Graceful and clear playbooks.
  • Simple is better than complex.
  • Complex is better than complicated.
  • Flat is better than nested.
  • Ansible modules are organised without hierarchy.
  • Ansible only uses name spaces for roles.
  • Explicit is better than implicit. Implicit can become invisible to users.
  • Ansible id very consistent.
  • Simple by design.
  • Easy to learn.

Docker + Python

by Tim Butler

  • Prefers to think of containers as application containers.
  • Docker is an abstraction layer focussed on the application it delivers.
  • Easy, repeatable deployments.
  • Not a fad, introduced 15 years again.
  • Google launch over 2 billion containers per week.
  • Docker is fast, lightweight, isolated and easy.
  • Rapidly changing and improving.
  • Quickly changing best practices.
  • Containers are immutable.
  • No mature multi-host deployment.
  • Security issues addressed via stopping containers and starting a patched one (milliseconds)
  • Simple and clear subcommands.
  • Docker compose for orchestration.
  • Docker machine creates to the Docker host for you.
  • Future
  • Volume plugin
  • New networking system so it actually works at scale.

Testing ain't hard, even for SysAdmins

by Geoff Crompton

  • Salt stack provides:
  • configuration management
  • loosely coupled infrastructure coordination.
  • Orchestration
    • remote execution
    • discovery
  • unittest 101
  • create a test directory
  • write a test
  • gave an example of a "hello world" of tests.
  • uses unittest.main.
  • Nose extends unittest to better facilitate multiple unit tests.
  • Mock allows the replacement of modules for testing.
  • Keep tests small.

Python on the move: The state of mobile Python

by Russell Keith-Magee

  • iOS
  • Claims Python on mobile is very viable.
  • Most of the failing bugs are not services you want on mobile anyway.
  • libffi problems needs to be resolved.
  • Android
  • Compiler issues not quite resolved.
  • libffi problems needs to be resolved.
  • What not Jython? Does not compile on Android. Nor will many of it's dependencies.
  • Jython is probably not the right solution anyway.
  • Thinks you may be able to compile Python directly to Java...uses Byterun as an example.
  • Kivy works now and worth using.
  • His project Toga is coming along nicely.
  • Admits he may be on a fools errand but thinks this is achievable.

Journey to becoming a Developer: an Administrators story

by Victor Palma

  • The sysadmin mindset of get things fixed as fast as possible needs to be shed.
  • Take the time to step back and consider problems.
  • Keep things simple, explicit and consistent.
  • Do comments in reStructured Text.
  • Unless you're testing, you're not really coding.
  • Tools include tox and nose.
  • Don't be afraid to experiment.
  • Find something you are passionate about and manipulate that data.

Guarding the gate with Zuul

by Joshua Hesketh

  • Gerrit does code review.
  • Zuul tests things right before they merge and will only merge them if they pass.
  • Only Zuul can commit to master.
  • Zuul uses gearman to manage Jenkins jobs.
  • Uses NNFI - nearest non-failing item
  • Use jenkins-gearman instead of jenkins-gerrit to reproduce the work flow.

OpenStack Miniconf at PyConAu
Posted by Craige McWhirter on

OpenStack: A Vision for the Future

by Monty Taylor

  • Create truth in realistic acting
  • Know what problem you're trying to solve.
  • Develop techniques to solve the problem.
  • Don't confuse the techniques with the result.
  • Willingness to change with new information.

What Monty Wants

  • Provide computers and networks that work.
  • Should not chase 12-factor apps.
  • Kubernetes / CoreOS are already providing these frameworks
  • OpenStack should provide a place for these frameworks to work.
  • By default give a directly routable IP.

inaugust.com/talks/a-vision-for-the-future.html

The Future of Identity (Keystone) in OpenStack

by Morgan Fainberg

  • Moving to Fernet Tokens as the default, everywhere.
  • Lightweight
  • No database requirement
  • Limited token size
  • Will support all the features of existing token types.
  • Problems with UUID or PKI tokens:
  • SQL back end
  • PKI tokens are too large.
  • Moving from bespoke WSGI to Flask
  • Moving to a KeystoneAuth Library to remove the need for the client to be everywhere.
  • Keystone V3 API...everywhere. Focus on removing technical debt.
  • V2 API should die.
  • Deprecating the Keystone client in favour of the openstack client.
  • Paste.ini functionality being moved to core and controlled via policy.json

Orchestration and CI/CD with Ansible and OpenStack

by Simone Soldateschi

  • Gave a great overview of OpenStack / CoreOS / Containers
  • All configuration management sucks. Ansible sucks less.
  • CI/CD pipelines are repeatable.

Practical Federation

by Jamie Lennox

  • SAML is the initially supported WebSSO.
  • Ipsilon has SAML frontend, supports SSSD / PAM on the backend.
  • Requires Keystone V3 API everywhere.
  • Jamie successfully did live demo that demonstrated the work flow.

Privesep

by Angus Lees

  • Uses Linux kernel separation to restrict available privileges.
  • Gave a brief history of rootwrap`.
  • Fast and safe.
  • Still in beta

OpenStack Works, so now what?

by Monty Taylor

  • Shade's existence is a bug.
  • Take OpenStack back to basics
  • Keeps things simple.

How To Configure Debian to Use The Tiny Programmer ISP Board
Posted by Craige McWhirter on

So, you've gone and bought yourself a Tiny Programmer ISP, you've plugged into your Debian system, excitedly run avrdude only to be greeted with this:

% avrdude -c usbtiny -p m8


avrdude: error: usbtiny_transmit: error sending control message: Operation not permitted
avrdude: initialization failed, rc=-1
         Double check connections and try again, or use -F to override
         this check.


avrdude: error: usbtiny_transmit: error sending control message: Operation not permitted

avrdude done.  Thank you.

I resolved this permissions error by adding the following line to /etc/udev/rules.d/10-usbtinyisp.rules:

SUBSYSTEM=="usb", ATTR{idVendor}=="1781", ATTR{idProduct}=="0c9f", GROUP="plugdev", MODE="0660"

Then restarting udev:

% sudo systemctl restart udev

Plugged the Tiny Programmer ISP back in the laptop and ran avrdude again:

% avrdude -c usbtiny -p m8

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e9587
avrdude: Expected signature for ATmega8 is 1E 93 07
         Double check chip, or use -F to override this check.

avrdude done.  Thank you.

You should now have avrdude love.

Enjoy :-)

How To Delete a Cinder Snapshot with a Status of error or error_deleting With Ceph Block Storage
Posted by Craige McWhirter on

When deleting a volume snapshot in OpenStack you may sometimes get an error message stating that Cinder was unable to delete the snapshot.

There are a number of reasons why a snapshot may be reported by Ceph as unable to be deleted, however the most common reason in my experience has been that a Cinder client connection has not yet been closed, possibly because a client crashed.

If you were to look at the snapshots in Cinder, the status is usually error or error_deleting:

% cinder snapshot-list
+--------------------------------------+--------------------------------------+----------------+------------------------------------------------------------------+------+
|                  ID                  |              Volume ID               |     Status     |                           Display Name                           | Size |
+--------------------------------------+--------------------------------------+----------------+------------------------------------------------------------------+------+
| 07d75992-bf3f-4c9c-ab4e-efccdfc2fe02 | 3004d6e9-7934-4c95-b3ee-35a69f236e46 |     error      | snappy:3004d6e9-7934-4c95-b3ee-35a69f236e46:2015-06-26T14:00:02Z |  40  |
| 2db84ec7-6e1a-41f8-9dc9-1dc14e6ecef0 | 3004d6e9-7934-4c95-b3ee-35a69f236e46 | error_deleting | snappy:3004d6e9-7934-4c95-b3ee-35a69f236e46:2015-05-18T00:00:01Z |  40  |
| 47fbbfe8-643c-4711-a066-36f247632339 | 3004d6e9-7934-4c95-b3ee-35a69f236e46 |   available    | snappy:3004d6e9-7934-4c95-b3ee-35a69f236e46:2015-06-29T03:00:14Z |  40  |
| 52c43ec8-e713-4f87-b329-3c681a3d31f2 | 3004d6e9-7934-4c95-b3ee-35a69f236e46 | error_deleting | snappy:3004d6e9-7934-4c95-b3ee-35a69f236e46:2015-06-24T14:00:02Z |  40  |
| a595180f-d5c5-4c4b-a18c-ca56561f36cc | 3004d6e9-7934-4c95-b3ee-35a69f236e46 |     error      | snappy:3004d6e9-7934-4c95-b3ee-35a69f236e46:2015-06-25T14:00:02Z |  40  |
+--------------------------------------+--------------------------------------+----------------+------------------------------------------------------------------+------+

When you check Ceph you may find the following snapshot list:

# rbd snap ls my.pool.cinder.block/volume-3004d6e9-7934-4c95-b3ee-35a69f236e46
SNAPID NAME                                              SIZE
  2069 snapshot-2db84ec7-6e1a-41f8-9dc9-1dc14e6ecef0 40960 MB
  2526 snapshot-52c43ec8-e713-4f87-b329-3c681a3d31f2 40960 MB
  2558 snapshot-47fbbfe8-643c-4711-a066-36f247632339 40960 MB

The astute will notice that there are only 3 snapshots listed in Ceph yet 5 listed in Cinder. We can immediately exclude 47fbbfe8 which is available in both Cinder and Ceph, so there's no issues there.

You will also notice that the snapshots with the status error are not in Ceph and the two with error_deleting are. My take on this is that for the status error, Cinder never received the message from Ceph stating that this had been deleted successfully. Whereas for the status error_deleting status, Cinder had been unsuccessful in offloading the request to Ceph.

Each status will need to be handled separately , I'm going to start with the error_deleting snapshots, which are still present in both Cinder and Ceph.

In MariaDB, set the status from error_deleting to available:

MariaDB [cinder]> update snapshots set status='available' where id = '2db84ec7-6e1a-41f8-9dc9-1dc14e6ecef0';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

MariaDB [cinder]> update snapshots set status='available' where id = '52c43ec8-e713-4f87-b329-3c681a3d31f2';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

Check in Cinder that the status of these snapshots has been updated successfully:

% cinder snapshot-list
+--------------------------------------+--------------------------------------+----------------+------------------------------------------------------------------+------+
|                  ID                  |              Volume ID               |     Status     |                           Display Name                           | Size |
+--------------------------------------+--------------------------------------+----------------+------------------------------------------------------------------+------+
| 07d75992-bf3f-4c9c-ab4e-efccdfc2fe02 | 3004d6e9-7934-4c95-b3ee-35a69f236e46 |     error      | tuttle:3004d6e9-7934-4c95-b3ee-35a69f236e46:2015-06-26T14:00:02Z |  40  |
| 2db84ec7-6e1a-41f8-9dc9-1dc14e6ecef0 | 3004d6e9-7934-4c95-b3ee-35a69f236e46 |   available    | tuttle:3004d6e9-7934-4c95-b3ee-35a69f236e46:2015-05-18T00:00:01Z |  40  |
| 47fbbfe8-643c-4711-a066-36f247632339 | 3004d6e9-7934-4c95-b3ee-35a69f236e46 |   available    | tuttle:3004d6e9-7934-4c95-b3ee-35a69f236e46:2015-06-29T03:00:14Z |  40  |
| 52c43ec8-e713-4f87-b329-3c681a3d31f2 | 3004d6e9-7934-4c95-b3ee-35a69f236e46 |   available    | tuttle:3004d6e9-7934-4c95-b3ee-35a69f236e46:2015-06-24T14:00:02Z |  40  |
| a595180f-d5c5-4c4b-a18c-ca56561f36cc | 3004d6e9-7934-4c95-b3ee-35a69f236e46 |     error      | tuttle:3004d6e9-7934-4c95-b3ee-35a69f236e46:2015-06-25T14:00:02Z |  40  |
+--------------------------------------+--------------------------------------+----------------+------------------------------------------------------------------+------+

Delete the newly available snapshots from Cinder:

% cinder snapshot-delete 2db84ec7-6e1a-41f8-9dc9-1dc14e6ecef0
% cinder snapshot-delete 52c43ec8-e713-4f87-b329-3c681a3d31f2

Then check the results in Cinder and Ceph:

% cinder snapshot-list
+--------------------------------------+--------------------------------------+----------------+------------------------------------------------------------------+------+
|                  ID                  |              Volume ID               |     Status     |                           Display Name                           | Size |
+--------------------------------------+--------------------------------------+----------------+------------------------------------------------------------------+------+
| 07d75992-bf3f-4c9c-ab4e-efccdfc2fe02 | 3004d6e9-7934-4c95-b3ee-35a69f236e46 |     error      | tuttle:3004d6e9-7934-4c95-b3ee-35a69f236e46:2015-06-26T14:00:02Z |  40  |
| 47fbbfe8-643c-4711-a066-36f247632339 | 3004d6e9-7934-4c95-b3ee-35a69f236e46 |   available    | tuttle:3004d6e9-7934-4c95-b3ee-35a69f236e46:2015-06-29T03:00:14Z |  40  |
| a595180f-d5c5-4c4b-a18c-ca56561f36cc | 3004d6e9-7934-4c95-b3ee-35a69f236e46 |     error      | tuttle:3004d6e9-7934-4c95-b3ee-35a69f236e46:2015-06-25T14:00:02Z |  40  |
+--------------------------------------+--------------------------------------+----------------+------------------------------------------------------------------+------+

# rbd snap ls my.pool.cinder.block/volume-3004d6e9-7934-4c95-b3ee-35a69f236e46
SNAPID NAME                                              SIZE
  2558 snapshot-47fbbfe8-643c-4711-a066-36f247632339 40960 MB

So we are done with Ceph now, as the error snapshots do not exist there. As they only exist in Cinder, we need to mark them as deleted in the Cinder database:

MariaDB [cinder]> update snapshots set status='deleted', deleted='1' where id = '07d75992-bf3f-4c9c-ab4e-efccdfc2fe02';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

MariaDB [cinder]> update snapshots set status='deleted', deleted='1' where id = 'a595180f-d5c5-4c4b-a18c-ca56561f36cc';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

Now check the status in Cinder:

% cinder snapshot-list
+--------------------------------------+--------------------------------------+-----------+------------------------------------------------------------------+------+
|                  ID                  |              Volume ID               |   Status  |                           Display Name                           | Size |
+--------------------------------------+--------------------------------------+-----------+------------------------------------------------------------------+------+
| 47fbbfe8-643c-4711-a066-36f247632339 | 3004d6e9-7934-4c95-b3ee-35a69f236e46 | available | tuttle:3004d6e9-7934-4c95-b3ee-35a69f236e46:2015-06-29T03:00:14Z |  40  |
+--------------------------------------+--------------------------------------+-----------+------------------------------------------------------------------+------+

Now your errant Cinder snapshots have been removed.

Enjoy :-)

How To Resolve a Volume is Busy Error on Cinder With Ceph Block Storage
Posted by Craige McWhirter on

When deleting a volume in OpenStack you may sometimes get an error message stating that Cinder was unable to delete the volume because the volume was busy:

2015-05-21 23:31:41.160 16911 ERROR cinder.volume.manager [req-6f77ef4d-bbff-4ff4-8a3e-4c6b264ac5ca \
04b7cb61dd3f4f2f8f80bbd9833addbd 5903e3bda1e840d492fe79fb840acacc - - -] Cannot delete volume \
f8867d43-bc82-404e-bcf5-6d345c32269e: volume is busy

There are a number of reasons why a volume may be reported by Ceph as busy, however the most common reason in my experience has been that a Cinder client connection has not yet been closed, possibly because a client crashed.

If you were to look at the volume in Cinder, that status is usually available, the record looks in order. When you check Ceph, you'll see that the volume still exists there too.

% cinder show f8867d43-bc82-404e-bcf5-6d345c32269e | grep status
|    status    |    available    |

 # rbd -p my.ceph.cinder.pool ls | grep f8867d43-bc82-404e-bcf5-6d345c32269e
 volume-f8867d43-bc82-404e-bcf5-6d345c32269e

Perhaps there's a lock on this volume. Let's check for locks and then remove them if we find one:

# rbd lock list my.ceph.cinder.pool/volume-f8867d43-bc82-404e-bcf5-6d345c32269e

If there are any locks on the volume, you can use lock remove using the id and locker from the previous command to delete the lock:

# rbd lock remove <image-name> <id> <locker>

What if there are no locks on the volume but you're still unable to delete it from either Cinder or Ceph? Let's check for snapshots:

# rbd -p my.ceph.cinder.pool snap ls volume-f8867d43-bc82-404e-bcf5-6d345c32269e
SNAPID NAME                                              SIZE
  2072 snapshot-33c4309a-d5f7-4ae1-946d-66ba4f5cdce3 25600 MB

When you attempt to delete that snapshot you will get the following:

# rbd snap rm my.ceph.cinder.pool/volume-f8867d43-bc82-404e-bcf5-6d345c32269e@snapshot-33c4309a-d5f7-4ae1-946d-66ba4f5cdce3
rbd: snapshot 'snapshot-33c4309a-d5f7-4ae1-946d-66ba4f5cdce3' is protected from removal.
2015-05-22 01:21:52.504966 7f864f71c880 -1 librbd: removing snapshot from header failed: (16) Device or resource busy

This reveals that it was the snapshot that was busy and locked all along.

Now we need to unprotect the snapshot:

# rbd snap unprotect my.ceph.cinder.pool/volume-f8867d43-bc82-404e-bcf5-6d345c32269e@snapshot-33c4309a-d5f7-4ae1-946d-66ba4f5cdce3

You should now be able to delete the volume and it's snapshot via Cinder.

Enjoy :-)

Rebuilding An OpenStack Instance and Keeping the Same Fixed IP
Posted by Craige McWhirter on

OpenStack and in particular the compute service, Nova, has a useful rebuild function that allows you to rebuild an instance from a fresh image while maintaining the same fixed and floating IP addresses, amongst other metadata.

However if you have a shared storage back end, such as Ceph, you're out of luck as this function is not for you.

Fortunately, there is another way.

Prepare for the Rebuild:

Note the fixed IP address of the instance that you wish to rebuild and the network ID:

$ nova show demoinstance0 | grep network
| DemoTutorial network                       | 192.168.24.14, 216.58.220.133                     |
$ export FIXED_IP=192.168.24.14
$ neutron floatingip-list | grep 216.58.220.133
| ee7ecd21-bd93-4f89-a220-b00b04ef6753 |                  | 216.58.220.133      |
$ export FLOATIP_ID=ee7ecd21-bd93-4f89-a220-b00b04ef6753
$ neutron net-show DemoTutorial | grep " id "
| id              | 9068dff2-9f7e-4a72-9607-0e1421a78d0d |
$ export OS_NET=9068dff2-9f7e-4a72-9607-0e1421a78d0d

You now need to delete the instance that you wish to rebuild:

$ nova delete demoinstance0
Request to delete server demoinstance0 has been accepted.

Manually Prepare the Networking:

Now you need to re-create the port and re-assign the floating IP, if it had one:

$ neutron port-create --name demoinstance0 --fixed-ip ip_address=$FIXED_IP $OS_NET
Created a new port:
+-----------------------+---------------------------------------------------------------------------------------+
| Field                 | Value                                                                                 |
+-----------------------+---------------------------------------------------------------------------------------+
| admin_state_up        | True                                                                                  |
| allowed_address_pairs |                                                                                       |
| binding:vnic_type     | normal                                                                                |
| device_id             |                                                                                       |
| device_owner          |                                                                                       |
| fixed_ips             | {"subnet_id": "eb5db27f-edad-480e-92cb-1f8fec8848a8", "ip_address": "192.168.24.14"}  |
| id                    | c1927578-451b-4682-8888-55c7163898a4                                                  |
| mac_address           | fa:16:3e:5a:39:67                                                                     |
| name                  | demoinstance0                                                                         |
| network_id            | 9068dff2-9f7e-4a72-9607-0e1421a78d0d                                                  |
| security_groups       | 5898c15a-4670-429b-a414-9f59671c4d8b                                                  |
| status                | DOWN                                                                                  |
| tenant_id             | gsu7j52c50804cf3aad71b92e6ced65e                                                      |
+-----------------------+---------------------------------------------------------------------------------------+
$ export OS_PORT=c1927578-451b-4682-8888-55c7163898a4
$ neutron floatingip-associate $FLOATIP_ID $OS_PORT
Associated floating IP ee7ecd21-bd93-4f89-a220-b00b04ef6753
$ neutron floatingip-list | grep $FIXED_IP
| ee7ecd21-bd93-4f89-a220-b00b04ef6753 | 192.168.24.14   | 216.58.220.133     | c1927578-451b-4682-8888-55c7163898a4 |

Re-build!

Now you need to boot the instance again and specify port you created:

$ nova boot --flavor=m1.tiny --image=MyImage --nic port-id=$OS_PORT demoinstance0
$ nova show demoinstance0 | grep network
| DemoTutorial network                       | 192.168.24.14, 216.58.220.133                     |

Now your rebuild has been completed, you've got your old IPs back and you're done. Enjoy :-)

Attaching Multiple Network Interfaces and Floating IPs to OpenStack Instances with Neutron
Posted by Craige McWhirter on

There are a number of use cases where you may need to connect multiple floating IPs to existing OpenStack instances. However the functionality to do this is not exposed via the Horizon Dashboard. This is how I go about attaching multiple network interfaces and floating IPs to OpenStack instances with Neutron.

Assumptions:

Port Creation and Assignment

When you have your environment sourced appropriately, get a list of networks for this tenant:

% neutron net-list
+--------------------------------------+--------------+-------------------------------------------------------+
| id                                   | name         | subnets                                               |
+--------------------------------------+--------------+-------------------------------------------------------+
| 85314baa-a022-4dd1-918c-a73c83c8cad6 | ext-net      | 9248bc58-6cfe-4ff8-b33e-286a60c96c6d 999.999.999.0/23 |
| ee31dc0e-e226-423d-a7fe-f564dc17614e | DemoTutorial | 5821de82-3843-46ce-a796-c801bf40fd4c 192.168.71.0/24  |
+--------------------------------------+--------------+-------------------------------------------------------+

We're interested in the non-external network. In this case "DemoTutorial". I normally set this to $OS_NET. Now we can create a new port on that network.

% export OS_NET=ee31dc0e-e226-423d-a7fe-f564dc17614e
% neutron port-create $OS_NET
Created a new port:
+-----------------------+---------------------------------------------------------------------------------------+
| Field                 | Value                                                                                 |
+-----------------------+---------------------------------------------------------------------------------------+
| admin_state_up        | True                                                                                  |
| allowed_address_pairs |                                                                                       |
| binding:vnic_type     | normal                                                                                |
| device_id             |                                                                                       |
| device_owner          |                                                                                       |
| fixed_ips             | {"subnet_id": "af150a1e-067a-4641-89a4-24c5b6b8fe3b", "ip_address": "192.168.71.180"} |
| id                    | fd2f78df-cf78-4394-84eb-9e37ed1e5624                                                  |
| mac_address           | fa:54:6e:f2:ce:a9                                                                     |
| name                  |                                                                                       |
| network_id            | ee31dc0e-e226-423d-a7fe-f564dc17614e                                                  |
| security_groups       | b1240686-7ad9-4d29-a679-d219f76648ca                                                  |
| status                | DOWN                                                                                  |
| tenant_id             | abcd639c50804cf3end71b92e6ced65e                                                      |
+-----------------------+---------------------------------------------------------------------------------------+

We now need to note the id or as I do, assign it to $PORT_ID. Next we fire up nova. I'm going to assume that you know either the instance name or ID and have assigned it to $INSTANCE.

% export PORT_ID=fd2f78df-cf78-4394-84eb-9e37ed1e5624
% export INSTANCE=3c7ae1b9-8111-4f15-9945-75e0af157ead
% nova interface-attach --port-id $PORT_ID $INSTANCE

You should now have successfully added a second network interface to your OpenStack instance. Let's double check that:

% nova show $INSTANCE | grep network
| DemoTutorial network                 | 192.168.71.180, 192.168.71.181

Great! Now you have two internal IP addresses, one for each port assigned to that tenant.

Assigning Floating IPs

You can now add floating IPs either via the Horizon Dashboard or via the neutron client. I'll cover how to do this via the CLI. Fire up neutron, locate the original port and assign it's UUID to $PORT_ID0:

% neutron port-list | grep 192.168.71.181
fa:46:7e:21:4f:f3 | {"subnet_id": "8f987932-48ee-4262-8b44-0c910512a387", "ip_address": "192.168.71.181"} |
% export PORT_ID0=8f987932-48ee-4262-8b44-0c910512a387

Then we get a list of available floating IPs and assign those to variables too:

% neutron floatingip-list
+--------------------------------------+------------------+---------------------+---------+
| id                                   | fixed_ip_address | floating_ip_address | port_id |
+--------------------------------------+------------------+---------------------+---------+
| 390e4676-0e05-40c3-9012-e5d27eb85dbe |                  | 999.999.999.123     |         |
| 16f7ca27-1d11-4967-9f0c-04f578590b01 |                  | 999.999.999.124     |         |
| f983b10d-454c-4c19-8f65-d9b96c4d7aa6 |                  | 999.999.999.125     |         |
+--------------------------------------+------------------+---------------------+---------+
% export FIP0=16f7ca27-1d11-4967-9f0c-04f578590b01
% export FIP1=f983b10d-454c-4c19-8f65-d9b96c4d7aa6
% neutron floatingip-associate $FIP0 $PORT_ID
Associated floating IP 16f7ca27-1d11-4967-9f0c-04f578590b01
% neutron floatingip-associate $FIP1 $PORT_ID0
Associated floating IP f983b10d-454c-4c19-8f65-d9b96c4d7aa6

We can then verify this assignment:

% neutron floatingip-list
+--------------------------------------+------------------+---------------------+---------+
| id                                   | fixed_ip_address | floating_ip_address | port_id |
+--------------------------------------+------------------+---------------------+---------+
| 390e4676-0e05-40c3-9012-e5d27eb85dbe |                  | 999.999.999.123     |         |
| 16f7ca27-1d11-4967-9f0c-04f578590b01 | 192.168.71.180   | 999.999.999.124     |         |
| f983b10d-454c-4c19-8f65-d9b96c4d7aa6 | 192.168.71.181   | 999.999.999.125     |         |
+--------------------------------------+------------------+---------------------+---------+

For good measure you can double check how Nova sees this assignment:'

% nova show $INSTANCE | grep network
| DemoTutorial network                 | 192.168.71.180, 192.168.71.181, 999.999.999.124, 999.999.999.125

You're done :-)

A Little Vim Hack For Go
Posted by Craige McWhirter on

After LCA2015 I've starting playing with Go (I blame Sven Dowideit). If you already use VIM-YouCompleteMe) then you should be right for most things Go. However I tinker in a few languages and you'll never guess that they have different rules around style and formatting of code.

Go is one out for me requiring settings unique to Go among the languages I tinker in. I made the below changes to my ~/.vimrc to suit Go:

function! GoSettings()
    set tabstop=7
    set shiftwidth=7
    set noexpandtab
endfunction
autocmd BufNewFile,BufFilePre,BufRead *.go :call GoSettings()

Now when I edit a file with the .go extension, my Vim session will be formatting the file correctly from the start.

You can also configure Vim to run gofmt but I preferred this approach.

Enjoy :-)

Configuring CoreOS Toolbox to Use Debian
Posted by Craige McWhirter on

The toolbox command in CoreOS uses Fedora by default. If you'd rather it used Debian by default, you can add the following lines to .toolboxrc:

TOOLBOX_DOCKER_IMAGE=debian
TOOLBOX_DOCKER_TAG=jessie

When you next run toolbox, you should see it pull down the requested image.

$ toolbox
Pulling repository debian
835c4d274060: Download complete
511136ea3c5a: Download complete
16386e29a1f4: Download complete
Status: Downloaded newer image for debian:jessie
core-debian-jessie
Spawning container core-debian-jessie on /var/lib/toolbox/core-debian-jessie.
Press ^] three times within 1s to kill container.
root@myserver:~#

It's that simple.