<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>OpenStack &#8211; Ryan D Lane</title>
	<atom:link href="https://blog.ryandlane.com/category/openstack/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.ryandlane.com</link>
	<description>A blog with rants about DevOps.</description>
	<lastBuildDate>Mon, 07 Dec 2015 20:50:50 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.8.21</generator>
<site xmlns="com-wordpress:feed-additions:1">4934144</site>	<item>
		<title>Per-project users and groups (aka service groups)</title>
		<link>https://blog.ryandlane.com/2013/06/27/per-project-users-and-groups-aka-service-groups/</link>
		<comments>https://blog.ryandlane.com/2013/06/27/per-project-users-and-groups-aka-service-groups/#comments</comments>
		<pubDate>Thu, 27 Jun 2013 18:51:14 +0000</pubDate>
		<dc:creator><![CDATA[Ryan Lane]]></dc:creator>
				<category><![CDATA[Devops]]></category>
		<category><![CDATA[LDAP]]></category>
		<category><![CDATA[MediaWiki]]></category>
		<category><![CDATA[OpenStack]]></category>
		<category><![CDATA[Virtualization]]></category>
		<category><![CDATA[Wikimedia]]></category>

		<guid isPermaLink="false">http://ryandlane.com/blog/?p=607</guid>
		<description><![CDATA[In Wikimedia Labs, we&#8217;re using OpenStack with heavy LDAP integration. With this integration we have a concept of global groups and users. When a user registers with Labs, the user&#8217;s account immediately becomes a global user, usable in all of Labs and its related infrastructure. When the user is added to an OpenStack project it&#8217;s [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>In Wikimedia Labs, we&#8217;re using OpenStack with heavy LDAP integration. With this integration we have a concept of global groups and users. When a user registers with Labs, the user&#8217;s account immediately becomes a global user, usable in all of Labs and its related infrastructure. When the user is added to an OpenStack project it&#8217;s also added to a global group, which is usable throughout the infrastructure.</p>
<p>Global users and groups are really useful for handing authentication and authorization at a global level, especially when interacting with things like Gerrit and other global services. Global users can also be used as service accounts within instances, between instances or between projects. There&#8217;s a number of downsides to global users though:</p>
<ol>
<li>The global user creation process is laborious.</li>
<li>Global users must provide an email address.</li>
<li>Global users have a fixed home directory in /home (which is an autofs NFS or GlusterFS mount).</li>
<li>Global users can authenticate to all services, even if that&#8217;s not necessary or wanted.</li>
<li>Global users must have shell rights and must be added to a project to be properly usable for data access inside of a project.</li>
<li>Users get confused when told to create Labs accounts to be used as service accounts.</li>
<li>If multiple users want to access a global user, it&#8217;s necessary for the credentials to be shared, or to have a project admin create a sudo policy.</li>
<li>Global users don&#8217;t have personal groups, but instead have global groups, which are projects. Limiting access to data for a global user is difficult.</li>
</ol>
<p>It&#8217;s also possible to define system users and groups via puppet and have those applied to instances within a project. There&#8217;s one major downside to this though: the changes would need to go through review first, which bottlenecks the process to the Operations team, and muddies up the puppet repository.</p>
<p>With the introduction of the <a href="https://tools.wmflabs.org/">Tools project</a>, as a <a href="https://meta.wikimedia.org/wiki/Toolserver">Toolserver</a> replacement, there was a really strong need for service users and groups that could be handled in a simple way. Our Tools project implementer, Marc-Andre Pelletier, had a novel concept: per-project users and groups.</p>
<h2>The concept and LDAP implementation</h2>
<p>Marc&#8217;s initial concept was to have another set of OUs, like <em>ou=project-people </em>and<em> ou=project-groups</em>, where we&#8217;d create sub-OUs per project. We adjusted the concept when I showed Marc how we&#8217;re currently handling <a title="Per-project sudo policies using sudo-ldap and puppet" href="http://ryandlane.com/blog/2012/04/24/per-project-sudo-policies-using-sudo-ldap-and-puppet/">per-project sudo</a>, though. Rather than using separate top-level OUs, we further extended the directory information tree (DIT) used by the OpenStack projects. Our OU for projects is <em>ou=projects,dc=wikimedia,dc=org</em> and the tools project OU is <em>ou=tools,ou=projects,dc=wikimedia,dc=org</em>. The extension for service groups also uses the sudo extension, and here&#8217;s the basic structure:</p>
<pre style="padding-left: 30px;">dn: cn=tools,ou=projects,dc=wikimedia,dc=org
objectClass: groupofnames
objectClass: extensibleobject
objectClass: top
cn: tools
info: servicegrouphomedirpattern=/data/project/%u
member: &lt;member-list-goes-here&gt;

# Single role, allowed to manage all project info
dn: cn=projectadmin,cn=tools,ou=projects,dc=wikimedia,dc=org
cn: projectadmin
roleOccupant: &lt;member-list-goes-here&gt;
objectClass: organizationalrole
objectClass: top

dn: ou=sudoers,cn=tools,ou=projects,dc=wikimedia,dc=org
ou: sudoers
objectClass: organizationalunit
objectClass: top

dn: ou=groups,cn=tools,ou=projects,dc=wikimedia,dc=org
ou: groups
objectClass: organizationalunit
objectClass: top

dn: ou=people,cn=tools,ou=projects,dc=wikimedia,dc=org
ou: people
objectClass: organizationalunit
objectClass: top</pre>
<p>Note: for the project definition we have a pretty ugly hack. We&#8217;re sticking configuration information into the OU using the info attribute and extensibleobject. We&#8217;re doing this so that both cli tools and the web interface can know how to handle service groups. We should define our own schema and extend the object properly, but this was a quick and dirty hack for handling it to meet a hackathon deadline.</p>
<p>Allowing the addition of service groups is easy enough. When a service group is requested, a user and group are added to <em>ou=people</em> and <em>ou=groups</em> respectively. However, this doesn&#8217;t make the service groups easily accessible. To solve this, we automatically add a project sudo policy for every service group. Here&#8217;s a single service group added to the DIT:</p>
<pre style="padding-left: 30px;">dn: cn=local-example,ou=groups,cn=tools,ou=projects,dc=wikimedia,dc=org
objectClass: groupofnames
objectClass: posixgroup
objectClass: top
gidNumber: 100000
member: &lt;member-list-goes-here&gt;
cn: local-example

dn: uid=local-example,ou=people,cn=tools,ou=projects,dc=wikimedia,dc=org
objectClass: person
objectClass: shadowaccount
objectClass: posixaccount
objectClass: top
uid: local-example
cn: local-example
sn: local-example
loginShell: /usr/local/bin/sillyshell
homeDirectory: /data/project/example/
uidNumber: 100000
gidNumber: 100000

dn: cn=runas-local-example,ou=sudoers,cn=tools,ou=projects,dc=wikimedia,dc=org
sudoOption: !authenticate
objectClass: sudorole
objectClass: top
sudoRunAsUser: local-example
sudoCommand: ALL
sudoUser: %local-example
cn: runas-local-example
sudoHost: ALL</pre>
<p>Project members can create service groups. The project member that creates the service group is the initial service group member. Members of the service group are allowed to add other members. All service group members can sudo to the service group without authentication.</p>
<p>The user and group have the same name, and the same uid/gid number. The uid and gid range were meant to be reserved and be allowed to overlap with service groups in other projects. Similarly, the user and group names were prefixed with local- and were to be allowed to overlap with service groups in other projects. The uid/gid range and non-unique user/group names design has changed since initial implementation, but I&#8217;ll get into that later.</p>
<h2>The instance implementation</h2>
<p>We&#8217;re using nslcd, which has support for defining multiple OUs for available services (passwd, shadow, group, etc.). To make service groups available on instances in a project, we use a similar approach as <a title="Per-project sudo policies using sudo-ldap and puppet" href="http://ryandlane.com/blog/2012/04/24/per-project-sudo-policies-using-sudo-ldap-and-puppet/">per-project sudo</a>. Puppet has a variable defined for the OpenStack project, which is then used when adding the service group specific OUs to nslcd.conf:</p>
<pre style="padding-left: 30px;"># root
base dc=wikimedia,dc=org

# Global users and groups
base passwd ou=people,dc=wikimedia,dc=org
base shadow ou=people,dc=wikimedia,dc=org
base group ou=groups,dc=wikimedia,dc=org

# Per-project users and groups (service groups)
base passwd ou=people,cn=tools,ou=projects,dc=wikimedia,dc=org
base shadow ou=people,cn=tools,ou=projects,dc=wikimedia,dc=org
base group ou=groups,cn=tools,ou=projects,dc=wikimedia,dc=org</pre>
<p>That there&#8217;s a pretty massive gotcha here: if any of the OUs don&#8217;t exist for a service, it breaks the entire service. It&#8217;s very important that the OUs exist for all projects in which this will be used.</p>
<h2>After-implementation changes and further changes to come</h2>
<p>We added service groups prior to the tools project ramp-up, which was in April 2013. Since then we&#8217;ve made some modifications from the original design.</p>
<p>The first issue we ran into was with non-globally-unique uids and gids. Users can have a large number of groups, due to multiple project membership and service group membership. We&#8217;re providing per-project NFS shares, and NFS has a 16 group limitation <a href="http://tools.ietf.org/html/rfc5531#page-25">defined in its RFC</a>. A way around this is to use the <em>&#8211;manage-gids</em> option in rpc.mountd. With manage-gids, the NFS server does the secondary group lookup and ignores whatever the client sends to it. Here&#8217;s where the problem with non-unique uids and gids comes in. The server needs to know about all groups in all projects. We sync group info from LDAP into the NFS server&#8217;s local groups file, and we can name the groups whatever we want, but for multi-tenancy purposes the uids and gids need to be unique. Also, in general, making the uids and gids unique makes it easier to integrate other services that aren&#8217;t natively multi-tenant.</p>
<p>The second issue is with non-unique service group names. It&#8217;s easier to integrate service groups into services that aren&#8217;t natively multi-tenant if the service group names are unique as well. We&#8217;ll be changing the naming scheme from being prefixed with local- to being prefixed with &lt;projectname&gt;- or some variant of that. We have a specific use case in mind, using Gerrit, for this change, but I&#8217;ll write a follow-up post about that.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.ryandlane.com/2013/06/27/per-project-users-and-groups-aka-service-groups/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	<post-id xmlns="com-wordpress:feed-additions:1">607</post-id>	</item>
		<item>
		<title>OpenStack wiki migration</title>
		<link>https://blog.ryandlane.com/2013/02/19/openstack-wiki-migration/</link>
		<comments>https://blog.ryandlane.com/2013/02/19/openstack-wiki-migration/#comments</comments>
		<pubDate>Tue, 19 Feb 2013 00:32:52 +0000</pubDate>
		<dc:creator><![CDATA[Ryan Lane]]></dc:creator>
				<category><![CDATA[MediaWiki]]></category>
		<category><![CDATA[OpenStack]]></category>

		<guid isPermaLink="false">http://ryandlane.com/blog/?p=600</guid>
		<description><![CDATA[On Feb 15th we migrated the MoinMoin powered OpenStack wiki to a new wiki powered by MediaWiki. Overall the migration went well. There was a large amount of cleanup that needed to get done, but we followed up the migration with a doc cleanup sprint. The wiki should be in a mostly good state. If [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>On Feb 15th we migrated the MoinMoin powered OpenStack wiki to a new wiki powered by MediaWiki. Overall the migration went well. There was a large amount of cleanup that needed to get done, but we followed up the migration with a doc cleanup sprint. The wiki should be in a mostly good state. If you happen to find any articles that need cleanup, be bold!</p>
<p>So, what&#8217;s new with the wiki?</p>
<ol>
<li>All articles now have discussion pages</li>
<li>It&#8217;s possible to make <a href="https://wiki.openstack.org/w/index.php?title=Special:Book&amp;bookcmd=render_article&amp;arttitle=Cinder&amp;oldid=17287&amp;writer=rl">PDFs out of individual pages</a> or to <a href="https://wiki.openstack.org/w/index.php?title=Special:Book&amp;bookcmd=book_creator&amp;referer=Main+Page">create a book</a> (as a PDF or an actual physical book) from collections of articles</li>
<li>Uploads are global and can be used in multiple articles</li>
<li>Templates can be <a href="http://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual">written using Lua</a></li>
<li><a href="http://www.mediawiki.org/wiki/Extension:Gadgets">Gadgets can be written using Javascript and CSS</a> and shared with all wiki users</li>
<li>Layout of articles can use <a href="http://twitter.github.com/bootstrap">Twitter&#8217;s Bootstrap</a>, thanks to the <a href="https://github.com/OSAS/strapping-mediawiki">strapping-mediawiki skin</a></li>
<li>There&#8217;s <a href="https://wiki.openstack.org/wiki/Quantum?useformat=mobile">a mobile view</a>, though mobile device detection won&#8217;t be enabled until next Wikimedia branch-point release (1-2 weeks)</li>
<li>Many more features available in MediaWiki that don&#8217;t exist in MoinMoin</li>
</ol>
<p>Let me know if there&#8217;s any issues you run into with the new wiki.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.ryandlane.com/2013/02/19/openstack-wiki-migration/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
	<post-id xmlns="com-wordpress:feed-additions:1">600</post-id>	</item>
		<item>
		<title>Extending a flatdhcp network the hard way</title>
		<link>https://blog.ryandlane.com/2012/10/03/extending-a-flatdhcp-network-the-hard-way/</link>
		<comments>https://blog.ryandlane.com/2012/10/03/extending-a-flatdhcp-network-the-hard-way/#comments</comments>
		<pubDate>Wed, 03 Oct 2012 18:57:20 +0000</pubDate>
		<dc:creator><![CDATA[Ryan Lane]]></dc:creator>
				<category><![CDATA[OpenStack]]></category>
		<category><![CDATA[Virtualization]]></category>
		<category><![CDATA[Wikimedia]]></category>

		<guid isPermaLink="false">http://ryandlane.com/blog/?p=581</guid>
		<description><![CDATA[The title may make you think there&#8217;s an easy way. No such luck. Nova has no facility for extending a flatdhcp network, and as far as I can tell Quantum also has no facility for doing so. Extending the flatdhcp network can be kind of a pain in the ass, so here&#8217;s how I handled [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>The title may make you think there&#8217;s an easy way. No such luck. Nova has no facility for extending a flatdhcp network, and as far as I can tell Quantum also has no facility for doing so.</p>
<p>Extending the flatdhcp network can be kind of a pain in the ass, so here&#8217;s how I handled it:</p>
<h2>Assumptions</h2>
<ul>
<li>Network before extension:
<ul>
<li>Network CIDR: 10.4.0.0/24</li>
<li>Broadcast: 10.4.0.255</li>
<li>Netmask: 255.255.255.0</li>
<li>Network ID: 2</li>
</ul>
</li>
<li>Network after extension:
<ul>
<li>Network CIDR: 10.4.0.0/21</li>
<li>Broadcast: 10.4.7.255</li>
<li>Netmask: 255.255.248.0</li>
<li>Network ID: 2</li>
</ul>
</li>
</ul>
<h2>Modify the network</h2>
<p>First modify the network via the database:</p>
<pre>mysql nova -e "UPDATE networks SET netmask=\"255.255.248.0\",cidr=\"10.4.0.0/21\",broadcast=\"10.4.7.255\" WHERE id=2;"</pre>
<h2>Add the fixed IPs</h2>
<p>Now it&#8217;s necessary to add all of the IP addresses in the range into the <em>fixed_ips</em> table. Additionally, the broadcast address in the original range should be modified so that it&#8217;s no longer reserved, and the new broadcast address should be marked as reserved.</p>
<pre>for i in {1..7}
do
    for j in {0..255}
    do
        mysql nova -e "INSERT INTO fixed_ips SET created_at=\"2012-10-01 19:24:21\",updated_at=\"2012-10-01 19:24:21\",deleted=0,address=\"10.4.${i}.${j}\",network_id=2,allocated=0,reserved=0,leased=0"
    done
done
mysql nova -e "UPDATE fixed_ips SET reserved=0 WHERE address=\"10.4.0.255\""
mysql nova -e "UPDATE fixed_ips SET reserved=1 WHERE address=\"10.4.7.255\""</pre>
<h2>Restart nova-network and nova-compute services</h2>
<p>I tried launching some instances after making this change, and got the following error popping up in my logs:</p>
<pre>2012-10-01 20:04:48 TRACE nova.rpc.amqp DetachedInstanceError: Parent instance &lt;Instance at 0x46fa150&gt; is not bound to a Session; lazy load operation of attribute 'instance_type' cannot proceed</pre>
<p>In the #openstack channel, zynzel mentioned that it&#8217;s because I needed to restart my nova-network service. Actually, I needed to restart all nova-network and all nova-compute services.</p>
<p>I ran into a likely unrelated issue during this as well. My nova-compute services were deadlocked. I&#8217;ve actually noticed this in the past as well. Clearing the lock files from <em>/var/lock/nova</em> then restarting the services fixed that issue, though I still need to trace this issue down.</p>
<h2>Remove the old gateway addresses</h2>
<p>The old gateway addresses, with the /24 CIDR, need to be removed from the bridge and from the routing table on the network nodes.</p>
<h2>Restart dnsmasq and nova-network</h2>
<p>After removing the addresses, it&#8217;s necessary to restart dnsmasq. Kill the processes, then restart nova-network again.</p>
<h2>Why doesn&#8217;t Nova and Quantum have this functionality?</h2>
<p>Neither Nova, nor Quantum seem to have operations to modify a network. It&#8217;s not a completely abnormal task to need to extend a network, to re-vlan it, or to change IP ranges. Hell, I still need to add IPv6 to my network and I need to make it multi-network-node; when I created the network neither of these features existed and there&#8217;s no way simple way to enable them now.</p>
<p>You can delete and re-create a network, but what happens to IP address assignments? What happens to DNS entries that were created via the DNS plugin for Nova? We really need the ability to modify networks, not just create and delete them.</p>
<h2>A user-unfriendly experience</h2>
<p>The above steps don&#8217;t really seem very difficult, but the actual steps involved assume fairly involved knowledge of the code. When in the middle of doing this, things are stressful and things are failing. It&#8217;s pretty user-unfriendly.</p>
<p>Additionally, when I asked about this in the #openstack channel, I was treated like I was stupid for not wanting to muck around with the database. I was told that it was my fault for creating a network that was too small and that it isn&#8217;t Nova&#8217;s job to fix my mistakes. I was told that I should &#8220;use Windows&#8221;; meaning that I&#8217;m expecting the software to hold my noob-ish hand.</p>
<p>I can muck in the database and trace code, but I think if users are forced to do that then we&#8217;re failing from a usability perspective.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.ryandlane.com/2012/10/03/extending-a-flatdhcp-network-the-hard-way/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	<post-id xmlns="com-wordpress:feed-additions:1">581</post-id>	</item>
		<item>
		<title>OpenStack Foundation Board Candidacy</title>
		<link>https://blog.ryandlane.com/2012/08/20/openstack-foundation-board-candidacy/</link>
		<comments>https://blog.ryandlane.com/2012/08/20/openstack-foundation-board-candidacy/#comments</comments>
		<pubDate>Mon, 20 Aug 2012 19:23:48 +0000</pubDate>
		<dc:creator><![CDATA[Ryan Lane]]></dc:creator>
				<category><![CDATA[OpenStack]]></category>

		<guid isPermaLink="false">http://ryandlane.com/blog/?p=572</guid>
		<description><![CDATA[Voting has started for the OpenStack board and I&#8217;m one of the 39 candidates. Many of the candidates have posted answers to a set of questions asked of all candidates. You can read my responses at the candidate site. Rather than reiterating those answers, I&#8217;d like to bring up some of the specific things I&#8217;d [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Voting has started for the OpenStack board and I&#8217;m one of the 39 candidates. Many of the candidates have posted answers to a set of questions asked of all candidates. You can read <a href="http://www.openstack.org/election/2012-board-election/candidates/#RyanLane">my responses at the candidate site</a>. Rather than reiterating those answers, I&#8217;d like to bring up some of the specific things I&#8217;d like to do as a board member.</p>
<h2>Fight for the users</h2>
<p>Being an OpenStack user is difficult, currently. Unless you have an OpenStack developer on your team, it&#8217;s difficult to even run OpenStack, let alone migrate between versions. Many deployments will run into bugs in the stable version of OpenStack and getting those bugs fixed and moved into the stable branch is difficult.</p>
<p>Even if your team has a developer, the process for getting fixes into stable is more difficult than getting fixes into master. In fact, it&#8217;s at minimum twice as hard, since a requirement of getting a fix into stable is that it it must be fixed in master first. Additionally, all fixes require tests. My complaint isn&#8217;t necessarily about the process, but about how there&#8217;s not much support wrapped around it.</p>
<p>It would be ideal to have a team that helps developers through the process of getting stable fixed. Additionally, the team should fix bugs on behalf of users who can&#8217;t fix the bugs themselves.</p>
<h2>Support the support team</h2>
<p>There&#8217;s a number of core infrastructure services that the community relies on: the blog, the wiki, Gerrit, Jenkins, etc. These services are supported by a great team sponsored by community members. Occasionally this team needs additional long-term or short-term resources, though. It&#8217;s not always easy to get a community member to sponsor contracts for development and support that don&#8217;t directly benefit them.</p>
<p>Additionally, we can&#8217;t fully rely on community members for core services. If a community member sponsors the majority of our core services, and later decides to leave the community, then the core services are at risk. We need to ensure we can keep the lights on, at minimum.</p>
<h2>Provide resources to solve support issues</h2>
<p>For both of the above issues, I&#8217;d like the foundation to reserve a portion of its budget to hire employees or contractors, and to buy hardware to help support the users and the support team.</p>
<p>The foundation should, of course, as a first priority encourage community members to provide needed resources, but it should also ensure that any gaps are covered, especially in regards to user engagement and ensuring the lights stay on. These must be top priorities if we want to continue to grow our community.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.ryandlane.com/2012/08/20/openstack-foundation-board-candidacy/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	<post-id xmlns="com-wordpress:feed-additions:1">572</post-id>	</item>
		<item>
		<title>Per-project sudo policies using sudo-ldap and puppet</title>
		<link>https://blog.ryandlane.com/2012/04/24/per-project-sudo-policies-using-sudo-ldap-and-puppet/</link>
		<comments>https://blog.ryandlane.com/2012/04/24/per-project-sudo-policies-using-sudo-ldap-and-puppet/#respond</comments>
		<pubDate>Tue, 24 Apr 2012 00:58:54 +0000</pubDate>
		<dc:creator><![CDATA[Ryan Lane]]></dc:creator>
				<category><![CDATA[LDAP]]></category>
		<category><![CDATA[MediaWiki]]></category>
		<category><![CDATA[OpenStack]]></category>
		<category><![CDATA[Virtualization]]></category>
		<category><![CDATA[Wikimedia]]></category>

		<guid isPermaLink="false">http://ryandlane.com/blog/?p=511</guid>
		<description><![CDATA[In Wikimedia Labs, we don&#8217;t manage authentication and authorization in the normal public cloud way. We don&#8217;t assume that an instance creator is managing auth for instances they create. Instead, all of Labs uses a single auth system for all projects and instances and a community manages project membership and auth. In the original design, [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>In Wikimedia Labs, we don&#8217;t manage authentication and authorization in the normal public cloud way. We don&#8217;t assume that an instance creator is managing auth for instances they create. Instead, all of Labs uses a single auth system for all projects and instances and a community manages project membership and auth.</p>
<p>In the original design, being a project member in <a href="https://labsconsole.wikimedia.org/wiki/Help:Terminology"><em>specific</em> projects</a> would automatically give you root via sudo and being a project member in a <a href="https://labsconsole.wikimedia.org/wiki/Help:Terminology"><em>global</em> project</a> would give you shell, but not root. We were handling this through puppet configuration. This was a fairly limiting system. Giving fine grained permissions wasn&#8217;t easy. The instances knew which users were a member of a project since the projects were also posix groups; however, they didn&#8217;t know which users were in the roles of that project, so there was no fined grained way to handle this.</p>
<p>sudo-ldap to the rescue. With sudo-ldap, we can manage sudo policies in LDAP, and those can be done in a per-project basis. Let me explain how we&#8217;re handling this while also ensuring the original assumed design still applies to old projects.</p>
<h2>Handling the sudo policies in LDAP</h2>
<p>To make sudo work per-project, we need to make a sudoers OU for each project. Projects are located at <em>ou=projects,dc=wikimedia,dc=org</em>. We have an example project at <em>cn=testproject,ou=projects,dc=wikimedia,dc=org</em>. We can create a new sudoers OU for this project, with a default policy (for backwards compatibility):</p>
<pre style="padding-left: 30px;">dn: ou=sudoers,cn=testproject,ou=projects,dc=wikimedia,dc=org
ou: sudoers
objectclass: organizationalunit
objectclass: top

dn: cn=default,ou=sudoers,cn=testproject,ou=projects,dc=wikimedia,dc=org
cn: default
objectClass: sudorole
objectClass: top
sudoCommand: ALL
sudoHost: ALL
sudoUser: ALL</pre>
<p>The above creates a sudoers OU underneath the project&#8217;s object and creates a default policy for that project that gives all users the ability to run all commands via sudo.</p>
<p>For every pre-existing <em>specific</em> project, I created an OU and a default policy, then for every pre-existing global project I only created the OU, ensuring everything continued working how things worked in the original design. Whenever a project is created the OU and a default policy is also now automatically created with the project.</p>
<h2>Configuring sudo on the instances</h2>
<p>Now we must configure the instances to pull their sudo policies from this OU. Here&#8217;s the puppet template we&#8217;re using for <em>/etc/sudo-ldap.conf</em>:</p>
<pre style="padding-left: 30px;">BASE            &lt;%= basedn %&gt;
URI             &lt;% servernames.each do |servername| -%&gt;ldap://&lt;%= servername %&gt;:389 &lt;% end -%&gt;

BINDDN          cn=proxyagent,ou=profile,&lt;%= basedn %&gt;
BINDPW          &lt;%= proxypass %&gt;
SSL             start_tls
TLS_CHECKPEER   yes
TLS_REQCERT     demand
TLS_CACERTDIR   /etc/ssl/certs
TLS_CACERTFILE  /etc/ssl/certs/&lt;%= ldap_ca %&gt;
TLS_CACERT      /etc/ssl/certs/&lt;%= ldap_ca %&gt;
&lt;% if ldapincludes.include?('sudo') then %&gt;SUDOERS_BASE    &lt;%= sudobasedn %&gt;&lt;% end %&gt;</pre>
<p>The <em>sudobasedn</em> variable is being set as this:</p>
<pre style="padding-left: 30px;">$sudobasedn = "ou=sudoers,cn=${instanceproject},ou=projects,${basedn}"</pre>
<p>For a more in-context view, you can <a href="https://labsconsole.wikimedia.org/wiki/Git#Restrictions_and_Anonymous_access">clone our repo</a>, or <a href="https://gerrit.wikimedia.org/r/gitweb?p=operations/puppet.git;a=tree;hb=production">browse it via gitweb</a>.</p>
<h2>Managing the sudo policies</h2>
<p>In the trunk version of the <a href="http://www.mediawiki.org/wiki/Extension:OpenStackManager">OpenStackManager extension</a>, I&#8217;ve added support for managing per-project sudo. Users must be a member of the sysadmin role to do so.</p>
<a href="https://blog.ryandlane.com/2012/04/24/per-project-sudo-policies-using-sudo-ldap-and-puppet/#gallery-511-1-slideshow">Click to view slideshow.</a>
]]></content:encoded>
			<wfw:commentRss>https://blog.ryandlane.com/2012/04/24/per-project-sudo-policies-using-sudo-ldap-and-puppet/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<post-id xmlns="com-wordpress:feed-additions:1">511</post-id>	</item>
		<item>
		<title>OpenStackManager 1.4 released</title>
		<link>https://blog.ryandlane.com/2012/04/06/openstackmanager-1-4-released/</link>
		<comments>https://blog.ryandlane.com/2012/04/06/openstackmanager-1-4-released/#comments</comments>
		<pubDate>Fri, 06 Apr 2012 00:36:56 +0000</pubDate>
		<dc:creator><![CDATA[Ryan Lane]]></dc:creator>
				<category><![CDATA[LDAP]]></category>
		<category><![CDATA[MediaWiki]]></category>
		<category><![CDATA[OpenStack]]></category>
		<category><![CDATA[Semantic MediaWiki]]></category>
		<category><![CDATA[Virtualization]]></category>
		<category><![CDATA[Wikimedia]]></category>

		<guid isPermaLink="false">http://ryandlane.com/blog/?p=506</guid>
		<description><![CDATA[The OpenStackManager extension is a web interface for OpenStack, and a manager for a fully integrated test and development network being written primarily for Wikimedia Foundation use. This release is mostly aimed at performance and usability. Here&#8217;s a list of changes: Added a project filter. Rather than showing all projects, only projects selected in the [&#8230;]]]></description>
				<content:encoded><![CDATA[<p><em>The <a href="http://www.mediawiki.org/wiki/Extension:OpenStackManager">OpenStackManager extension</a> is a web interface for <a href="http://www.openstack.org/">OpenStack</a>, and a manager for a fully integrated test and development network being <a href="../2011/01/02/building-a-test-and-development-infrastructure-using-openstack/">written primarily for Wikimedia Foundation use</a>.</em></p>
<p>This release is mostly aimed at performance and usability. Here&#8217;s a list of changes:</p>
<ul>
<li>Added a project filter. Rather than showing all projects, only projects selected in the project filter will show in the management interfaces. This should make the interfaces contain far less text, and should make interfaces load much faster.</li>
<li>Refactored the list pages so that styles can be applied to all pages easily. Applied a couple CSS styles globally across all of the pages. For instance, the table text has been changed to be top aligned, to make large tables easier to handle.</li>
<li>Merged in Platonides&#8217;s change for handling SSH keys uploaded in formats other than OpenSSH format. Keys in non-OpenSSH format will automatically be converted, if possible. If a private key, or a key in a bad formatted is uploaded, it&#8217;ll be rejected.</li>
<li>Changed the project section collapsing behavior. Rather than the project title collapsing the project&#8217;s section, a &#8220;Toggle&#8221; action will do so. The project name has been changed back to being a link to the project&#8217;s page.</li>
<li>Projects are now sorted alphabetically everywhere.</li>
<li>Various fixes related to the PHP aws-sdk.</li>
<li>Move creation forms to list pages for many management pages, to avoid extra clicks where possible.</li>
<li>Various memcache support additions and fixes.</li>
<li>Added a fix to allow user creation through MediaWiki interface.</li>
</ul>
<p>If you&#8217;d like to help develop this extension, I&#8217;ve created a development environment in a project in Wikimedia Labs. Find me on #wikimedia-labs on Freenode or email me to get a labs account and access to the project.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.ryandlane.com/2012/04/06/openstackmanager-1-4-released/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	<post-id xmlns="com-wordpress:feed-additions:1">506</post-id>	</item>
		<item>
		<title>Fixing a very broken instance live migration manually</title>
		<link>https://blog.ryandlane.com/2012/01/06/fixing-a-very-broken-instance-live-migration-manually/</link>
		<comments>https://blog.ryandlane.com/2012/01/06/fixing-a-very-broken-instance-live-migration-manually/#respond</comments>
		<pubDate>Fri, 06 Jan 2012 02:13:57 +0000</pubDate>
		<dc:creator><![CDATA[Ryan Lane]]></dc:creator>
				<category><![CDATA[OpenStack]]></category>
		<category><![CDATA[Virtualization]]></category>

		<guid isPermaLink="false">http://ryandlane.com/blog/?p=502</guid>
		<description><![CDATA[I had a situation recently where a number of live migrations failed in a truly nasty way. The live migration failed part way through, but didn&#8217;t properly back-out the changes. This left the instance running nowhere, but in a &#8220;migrate&#8221; state in the database. I tried to reboot the instance, which then left the instance [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>I had a situation recently where a number of live migrations failed in a truly nasty way. The live migration failed part way through, but didn&#8217;t properly back-out the changes. This left the instance running nowhere, but in a &#8220;migrate&#8221; state in the database. I tried to reboot the instance, which then left the instance in the &#8220;running&#8221; state.</p>
<p>Of course, the instance wasn&#8217;t actually running anywhere and the reboot command wouldn&#8217;t start the instance, because it thought it was running. The logs complained that the instance wasn&#8217;t running whether I tried to restart the migration, or reboot. What a full of fail situation.</p>
<p>So, to fix this, I needed to make the instance actually start. In this situation, the database thought the instance was running on host virt2, but the instance&#8217;s libvirt files were on virt4. I copied the nwfilter file across to /etc/libvirt/nwfilter, then the domain file across to /etc/libvirt/qemu. I then created the nwfilter, then the domain:</p>
<pre style="padding-left: 30px;">virsh nwfilter-define /etc/libvirt/nwfilter/&lt;instance-nwfilter&gt;.xml
virsh create /etc/libvirt/qemu/&lt;instance-domain&gt;.xml</pre>
<p>Once the instance was started, I re-migrated the instance and all was good.</p>
<p>As a side note, I think what caused the migration failure was that I tried to migrate too many instances at the same time from a host that was already slightly overloaded. Of course, this is no excuse for nova to fail.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.ryandlane.com/2012/01/06/fixing-a-very-broken-instance-live-migration-manually/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<post-id xmlns="com-wordpress:feed-additions:1">502</post-id>	</item>
		<item>
		<title>OpenStackManager version 1.3 released</title>
		<link>https://blog.ryandlane.com/2011/12/22/openstackmanager-version-1-3-released/</link>
		<comments>https://blog.ryandlane.com/2011/12/22/openstackmanager-version-1-3-released/#respond</comments>
		<pubDate>Thu, 22 Dec 2011 15:30:10 +0000</pubDate>
		<dc:creator><![CDATA[Ryan Lane]]></dc:creator>
				<category><![CDATA[LDAP]]></category>
		<category><![CDATA[MediaWiki]]></category>
		<category><![CDATA[OpenStack]]></category>
		<category><![CDATA[Semantic MediaWiki]]></category>
		<category><![CDATA[Virtualization]]></category>
		<category><![CDATA[Wikimedia]]></category>

		<guid isPermaLink="false">http://ryandlane.com/blog/?p=499</guid>
		<description><![CDATA[The OpenStackManager extension is a web interface for OpenStack, and a manager for a fully integrated test and development network being written primarily for Wikimedia Foundation use. I&#8217;ve been busy enough lately working on our OpenStack infrastructure that I haven&#8217;t made an OpenStackManager release in a while. Over the past seven months I&#8217;ve continued to [&#8230;]]]></description>
				<content:encoded><![CDATA[<p><em>The <a href="http://www.mediawiki.org/wiki/Extension:OpenStackManager">OpenStackManager extension</a> is a web interface for <a href="http://www.openstack.org/">OpenStack</a>, and a manager for a fully integrated test and development network being <a href="../2011/01/02/building-a-test-and-development-infrastructure-using-openstack/">written primarily for Wikimedia Foundation use</a>.</em></p>
<p>I&#8217;ve been busy enough lately working on our OpenStack infrastructure that I haven&#8217;t made an OpenStackManager release in a while. Over the past seven months I&#8217;ve continued to make small changes to the software, and the past few weeks I&#8217;ve added features I feel deserve another release.</p>
<p>This is a bugfix and features release. Major changes include compatibility for cactus and diablo releases of nova, and 1.18 compatibility for MediaWiki. The changes in this release focused mainly on making workflow easier. Here&#8217;s a complete list of changes:</p>
<ul>
<li>Added a reboot action for instances</li>
<li>Made compatibility changes for cactus and diablo nova releases</li>
<li>Made compatibility changes for MediaWiki 1.18</li>
<li>Added support for configurable naming attributes</li>
<li>Added support for adding objectclasses and attributes for users that are missing them</li>
<ul>
<li>It&#8217;s now possible for MediaWiki to no longer have to create users, only update select user attributes and objectclasses</li>
</ul>
<li>Made a bunch of bugfixes regarding security groups</li>
<li>Added support for wildcard DNS entries</li>
<li>Added realm and instancename variables to puppet default variables, so that they can be used in puppet runs</li>
<li>Added support for wiki page creation for Projects</li>
<li>Added support for configuring default images for instances</li>
<li>Added support for creating server admin logs per project</li>
<li>Added support for default security group rules on project creation</li>
<li>Added dialog to project creation for adding members to projects and roles upon creation</li>
<li>Added support for managing puppet classes and variables through the interface, rather than LocalSettings.php</li>
<li>Made a usability change to instance creation: the default security group will always be selected by default</li>
<li>Added support for including the ssh key fingerprint of an instance in the &#8220;your instance is ready&#8221; emails</li>
<li>Made a usability change to only show actions to users if they can perform them</li>
<li>Lots of other minor bug fixes</li>
<li>Bugfixes from John Du Hart, Sam Reed and Mark Hershberger</li>
</ul>
<p>If you&#8217;d like to help develop this extension, I&#8217;ve created a development environment in a project in Wikimedia Labs. Find me on #wikimedia-labs on Freenode or email me to get a labs account and access to the project.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.ryandlane.com/2011/12/22/openstackmanager-version-1-3-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<post-id xmlns="com-wordpress:feed-additions:1">499</post-id>	</item>
		<item>
		<title>A process for puppetization of a service using Nova</title>
		<link>https://blog.ryandlane.com/2011/11/02/a-process-for-puppetization-of-a-service-using-nova/</link>
		<comments>https://blog.ryandlane.com/2011/11/02/a-process-for-puppetization-of-a-service-using-nova/#comments</comments>
		<pubDate>Wed, 02 Nov 2011 01:20:46 +0000</pubDate>
		<dc:creator><![CDATA[Ryan Lane]]></dc:creator>
				<category><![CDATA[MediaWiki]]></category>
		<category><![CDATA[OpenStack]]></category>
		<category><![CDATA[Virtualization]]></category>
		<category><![CDATA[Wikimedia]]></category>
		<category><![CDATA[Workflow]]></category>

		<guid isPermaLink="false">http://ryandlane.com/blog/?p=490</guid>
		<description><![CDATA[For the proper automation of a service using puppet, it&#8217;s necessary to ensure the service can be installed repeatedly, and that the service is fully up and ready when it is built. To ensure this, I&#8217;m using the following process, using nova: Create an instance and use it to do experimentation with the service. Document [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>For the proper automation of a service using puppet, it&#8217;s necessary to ensure the service can be installed repeatedly, and that the service is fully up and ready when it is built. To ensure this, I&#8217;m using the following process, using nova:</p>
<ol>
<li>Create an instance and use it to do experimentation with the service.</li>
<li>Document the service, along with the installation process on <a href="http://wikitech.wikimedia.org/view/Main_Page">wikitech</a>, after ensuring the service is working properly.</li>
<li>Create a second instance. Following the documentation written, puppetize the service.</li>
<li>Create a third instance. Ensure the puppetized service runs properly when initialized from scratch.</li>
<li>Kill all three instances, and replace the instances in the test cluster.</li>
</ol>
<p>When a service changes in puppet, follow the above cycle as well.</p>
<p>Using this process, I can be assured the puppet manifests, as written, will allow me to repeatedly install this service.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.ryandlane.com/2011/11/02/a-process-for-puppetization-of-a-service-using-nova/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	<post-id xmlns="com-wordpress:feed-additions:1">490</post-id>	</item>
		<item>
		<title>Sharing home directories to instances within a project using puppet, LDAP, autofs, and Nova</title>
		<link>https://blog.ryandlane.com/2011/11/01/sharing-home-directories-to-instances-within-a-project-using-puppet-ldap-autofs-and-nova/</link>
		<comments>https://blog.ryandlane.com/2011/11/01/sharing-home-directories-to-instances-within-a-project-using-puppet-ldap-autofs-and-nova/#comments</comments>
		<pubDate>Tue, 01 Nov 2011 17:49:13 +0000</pubDate>
		<dc:creator><![CDATA[Ryan Lane]]></dc:creator>
				<category><![CDATA[LDAP]]></category>
		<category><![CDATA[MediaWiki]]></category>
		<category><![CDATA[OpenStack]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[Virtualization]]></category>
		<category><![CDATA[Wikimedia]]></category>

		<guid isPermaLink="false">http://ryandlane.com/blog/?p=482</guid>
		<description><![CDATA[As mentioned in an older post, I&#8217;m building a test and development environment using OpenStack. The environment is intended to be fairly integrated. Part of this integration is a consistent working environment between instances in a project. Providing home directories via NFS is the easiest way of ensuring this consistent working environment. The problem with [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>As <a href="http://ryandlane.com/blog/2011/01/02/building-a-test-and-development-infrastructure-using-openstack/">mentioned in an older post</a>, I&#8217;m building a test and development environment using OpenStack. The environment is intended to be fairly integrated. Part of this integration is a consistent working environment between instances in a project. Providing home directories via NFS is the easiest way of ensuring this consistent working environment.</p>
<p>The problem with NFS home directories, however, is that they are fairly insecure. They can be used between instances to escalate privileges. In our environment, this isn&#8217;t a problem for instances within a project. If a user is a member of a project, they have shell on all instances. If they are given sudo access in a project, they are given sudo access on all instances. Between projects, however, is a problem. user-A with root on instance-A in project-A could su to to user-B on instance-A, modify the user&#8217;s <em>authorized_keys</em> file, and then have access to project-B if home directories are shared across projects.</p>
<p>To avoid cross-project escalation, each project needs its own set of home directories. This means we can&#8217;t simply export <em>/home</em> to the instance&#8217;s private network and be done with it. We&#8217;ll need to create an <em>exports</em> file, and share different directory trees with specific instances. We&#8217;ll also need to mount home directories differently on the instances, depending on the project they belong to.</p>
<p>To do so, we&#8217;ll use a combination of puppet, LDAP, autofs, and Nova.</p>
<h2>Creating the exports file</h2>
<p>To create the exports file we need three things:</p>
<ol>
<li>A list of projects</li>
<li>A list of instances within each project</li>
<li>A list of home directory locations for each project</li>
</ol>
<p>The first two can be found via LDAP. The query for a list of projects is: <em>&#8216;(&amp;(objectclass=groupofnames)(owner=*))&#8217;</em>. The query for a list of instances within each project is:<em> &#8216;(puppervar=instanceproject=&lt;project&gt;)&#8217;</em>. Of course, this approach is only usable for people using the <a href="http://www.mediawiki.org/wiki/Extension:OpenStackManager">OpenStackManager extension for MediaWiki</a>; I&#8217;ll mention more portable ways to get this information later in the post.</p>
<p>The third we can extrapolate, we just need a base directory. I chose to use <em>/export/home/&lt;project&gt;</em> for the locations.</p>
<p>I wrote a <a href="http://svn.wikimedia.org/viewvc/mediawiki/trunk/tools/subversion/user-management/manage-exports?view=markup">python script</a> that will pull this information, and create an exports file that looks like this:</p>
<pre style="padding-left: 30px;">/export/home/&lt;project1&gt; &lt;project1-instance1&gt;(rw,no_subtree_check) &lt;project-instance2&gt;(rw,no_subtree_check) &lt;project_instance...&gt;(rw,no_subtree_check)
/export/home/&lt;project2&gt; &lt;project2-instance1&gt;(rw,no_subtree_check) &lt;project2-instance2&gt;(rw,no_subtree_check) &lt;project2_instance...&gt;(rw,no_subtree_check)</pre>
<h2>Mounting the shares from the instances</h2>
<p>Each instance needs to mount the share, depending on its project. There&#8217;s a number of ways we can do this, but I like the flexibility of using autofs and LDAP to manage NFS mounts. To add slightly more flexibility we&#8217;ll involve the help of puppet as well.</p>
<p>In LDAP, we can create autofs entries by <a href="http://wikitech.wikimedia.org/view/Ldap#NisMap_entries_.28autofs.29">making maps and objects</a>. The following objects add support for <em>/home</em>:</p>
<pre style="padding-left: 30px;">dn: nisMapName=auto.master,&lt;basedn&gt;
objectClass: top
objectClass: nisMap
nisMapName: auto.master

dn: nisMapName=auto.home,&lt;basedn&gt;
objectClass: top
objectClass: nisMap
nisMapName: auto.home</pre>
<pre style="padding-left: 30px;">dn: nisMapName=/home,nisMapName=auto.master,&lt;basedn&gt;
objectClass: top
objectClass: nisObject
cn: /home
nisMapEntry: ldap:nisMapName=auto.home,&lt;basedn&gt;
nisMapName: auto.master</pre>
<p>We also need to add entries for the specific home directories. Here we are going to invoke a <a title="LDAP automount entry interoperability between Red Hat Enterprise Linux and Solaris for NFSv4" href="http://ryandlane.com/blog/2010/02/09/ldap-automount-entry-interoperability-between-red-hat-enterprise-linux/">little awesome magic that autofs has</a>: variables. Here&#8217;s the entry we are using for all home directories in all projects:</p>
<pre style="padding-left: 30px;">dn: cn=*,nisMapName=auto.home,&lt;basedn&gt;
changetype: add
nisMapEntry: ${SERVNAME}:${HOMEDIRLOC}/&amp;
objectClass: nisObject
objectClass: top
nisMapName: auto.home
cn: *</pre>
<p>We only need the one entry, which saves us from having to create and delete entries on creation and deletion of projects. Using this, however, means we need to set the variables. This is where puppet comes in. First, though, let&#8217;s look at the node in LDAP:</p>
<pre style="padding-left: 30px;">dn: dc=i-0000005c,dc=pmtpa,ou=hosts,dc=wikimedia,dc=org
objectClass: domainrelatedobject
objectClass: dnsdomain
objectClass: domain
objectClass: puppetclient
objectClass: dcobject
objectClass: top
puppetVar: realm=labs
puppetVar: writable=false
puppetVar: db_cluster=s1
puppetVar: instancecreator_email=rlane@wikimedia.org
puppetVar: instancecreator_username=Ryan Lane
puppetVar: instancecreator_lang=en
puppetVar: instanceproject=testlabs
puppetClass: base
puppetClass: ldap::client::wmf-test-cluster
puppetClass: exim::simple-mail-sender
puppetClass: db::core
puppetClass: mysql::mysqluser
puppetClass: mysql::datadirs
puppetClass: mysql::conf
l: pmtpa
associatedDomain: i-0000005c.pmtpa.wmflabs
associatedDomain: labs-db2.pmtpa.wmflabs
dc: i-0000005c
aRecord: 10.4.0.12</pre>
<p>All the above <em>objectclasses</em> and <em>attributes</em> are available for use in puppet. The really important one here is <em>instanceproject=testlabs</em>.</p>
<p>We can set the <em>autofs</em> variables via the <em><em>OPTIONS</em> </em>variable in the<em> /etc/default/autofs</em> file<em></em>:</p>
<p style="padding-left: 30px;">OPTIONS=&#8221;-DSERVNAME=&lt;%= nfs_server_name %&gt; -DHOMEDIRLOC=&lt;%= homedir_location %&gt;&#8221;</p>
<p>Here <em>SERVNAME</em> and <em>HOMEDIRLOC</em> <em>autofs</em> variables are being set. <em>nfs_server_name</em> and <em>homedir_location</em> are being set <a href="https://gerrit.wikimedia.org/r/gitweb?p=operations/puppet.git;a=blob;f=templates/ldap/autofs.default.erb;h=f54b3b8d2d57fa3c2c5e67f210119b677d043d27;hb=HEAD">via a puppet template</a>. Both are being determined <a href="https://gerrit.wikimedia.org/r/gitweb?p=operations/puppet.git;a=blob;f=manifests/ldap.pp;h=826145bc5cc98c301ba22d52e2f3bc5b9f122c4f;hb=HEAD">via a manifest</a>:</p>
<pre style="padding-left: 30px;">$homedir_location = "/export/home/${instanceproject}"</pre>
<p><em>nfs_server_name</em> is a hash, based on the project:</p>
<pre style="padding-left: 30px;">$nfs_server_name = $instanceproject ? {
	default =&gt; "labs-nfs1",
}</pre>
<p>I chose to use a hash based on project so that I can choose to separate the server based on project as well, if needed for performance, or extra security.</p>
<h2>Managing user home directories</h2>
<p>Everything up to this point is just creating the shares. However, we must maintain the users&#8217; home directories as well. For this, we need to know which users are in which projects, and we need to manage their home directories per project.</p>
<p>I <a href="http://svn.wikimedia.org/viewvc/mediawiki/trunk/tools/subversion/user-management/homedirectorymanager.py?view=markup">wrote a script</a> to search for users, based on a group (the project), that selectively creates/deletes/renames home directories and <em>authorized_keys</em> files. I should note here that I don&#8217;t use nova&#8217;s mechanisms for SSH key management, as it isn&#8217;t portable between applications. I instead store the keys in the user&#8217;s LDAP entry.</p>
<p>There&#8217;s a security issue with management of home directories. If a user is added to a project and we create a home directory, with a populated <em>authorized_keys</em> file, then remove the user from the project, but don&#8217;t remove their home directory, the user will still have access to the project&#8217;s instances. There&#8217;s two ways I go about solving this issue:</p>
<ol>
<li>Ensure the user only has access to the instance if they are in the project, <a href="https://gerrit.wikimedia.org/r/gitweb?p=operations/puppet.git;a=blob;f=templates/ldap/access.conf.erb;h=94263ea4382e0c86643a8aaf1c4d31745116cfaf;hb=HEAD">using <em>access.conf</em></a>. In my architecture, when projects are added, they are also made a <em>posixgroup</em>, with a <em>gid</em>. Thanks to this, we can treat the project as a system group in all instances. In <em>access.conf</em> we limit access to the project group.</li>
<li>User&#8217;s home directories are moved from <em>/export/home/&lt;project&gt;/&lt;user&gt;</em> to <em>/export/home/&lt;project&gt;/SAVE/&lt;user&gt;</em> when they are removed from the project.</li>
</ol>
<h2>Problems with this solution, and future improvements to make</h2>
<p>The major shortcoming of this solution is that it isn&#8217;t terribly portable. It is dependent on using LDAP, and storing specific information in the LDAP directory. Using the nova tools, or having nova manage the exports on instance creation/deletion would make this a much more portable solution.</p>
<p>Another shortcoming is that it isn&#8217;t terribly scalable. The exports file is being created from scratch every single script run (which needs to happen fairly frequently). Ideally, nova would write to a queue, and the NFS instance would add/remove instances from the exports as instances are created/deleted.</p>
<p>Thankfully, I didn&#8217;t have a shortage of ideas about how to accomplish this, <a href="http://www.mediawiki.org/wiki/WMF_Projects/Wikimedia_Labs/Shared_home_directories_per_project">as shown in my proposal</a>. I decided upon the quick and dirty approach, opting to do one of the more reusable approaches later. I&#8217;ll likely add support to nova for this at some time in the future.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.ryandlane.com/2011/11/01/sharing-home-directories-to-instances-within-a-project-using-puppet-ldap-autofs-and-nova/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	<post-id xmlns="com-wordpress:feed-additions:1">482</post-id>	</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: https://www.w3-edge.com/products/

Object Caching 1421/1493 objects using memcached
Page Caching using memcached
Database Caching 1/20 queries in 0.020 seconds using memcached

 Served from: blog.ryandlane.com @ 2023-01-21 11:58:13 by W3 Total Cache -->