libcloud-notifications mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From to...@apache.org
Subject svn commit: r1885921 [4/5] - in /libcloud/site/trunk: generated/ generated/blog/ generated/blog/2021/01/25/ generated/blog/archives/2021/01/ generated/blog/page/10/ generated/blog/page/11/ generated/blog/page/12/ generated/blog/page/13/ generated/blog/...
Date Tue, 26 Jan 2021 22:09:49 GMT
Modified: libcloud/site/trunk/generated/blog/page/4/index.html
URL: http://svn.apache.org/viewvc/libcloud/site/trunk/generated/blog/page/4/index.html?rev=1885921&r1=1885920&r2=1885921&view=diff
==============================================================================
--- libcloud/site/trunk/generated/blog/page/4/index.html (original)
+++ libcloud/site/trunk/generated/blog/page/4/index.html Tue Jan 26 22:09:48 2021
@@ -97,6 +97,68 @@
     
       <div class="post">
   
+    <h2><a href="/blog/2019/08/27/clemens-wolff-joins-our-team.html">Clemens Wolff (clewolff) joins our team</a></h2>
+  
+
+  
+    
+  
+  <span class="post-date-author">By Tomaz Muraus <span style="display:none">(<a href="https://plus.google.com/+TomazMuraus?rel=author">Google+</a>)</span>on Aug 27, 2019</span>
+
+  <div class="post-content">
+    <p>Please help us extend a warm welcome to our newest team member <a href="https://github.com/c-w">Clemens
+Wolff</a>!</p>
+
+<p>The Project Management Committee (PMC) for Apache Libcloud has invited Clemens
+Wolff to join us as a committer and we are pleased to announce that he
+has accepted.</p>
+
+<p>Clemens has participated in the Libcloud community for a while now and during
+his participation he made a <a href="https://github.com/apache/libcloud/pulls?q=is%3Apr+author%3Ac-w">number of high quality contributions to the
+project</a>.</p>
+
+<p>For anyone who would like to know more about Clemens here is his short bio:</p>
+
+<blockquote>
+<p>Clemens Wolff is a tech lead in Microsoft’s Commercial Software
+Engineering team, enabling customers from around the world to create scalable,
+resilient and efficient software solutions applying relevant technologies and
+platforms, including cloud computing, highly scalable data engines, machine
+learning and analytics, and distributed messaging systems.</p>
+</blockquote>
+
+<p>And in his own words:</p>
+
+<blockquote>
+<p>I was introduced to Libcloud while working with a research group at Imperial
+College London on porting OKpy, an open source computer science classroom
+management system, from GCP to Azure. OKpy uses Libcloud which made
+migrating the object storage needs of the application a breeze. Since this
+initial exposure, I’ve been using Libcloud on many projects to ensure
+cross-cloud compatibility and to simplify testing via the local provider
+implementations. Most of my contributions have been about maintaining and
+updating the Azure implementation of Libcloud’s storage driver and
+building test automation to ensure that Libcloud can seamlessly be used
+with Azure.</p>
+</blockquote>
+
+<p>We are happy to have him in our team and we are looking forward to his future
+participation and contributions.</p>
+
+  </div>
+
+  <div class="row section post-meta">
+    <div class="col-md-12 post-tags">
+      <p>Tags: <a href="/blog/tags/news.html" rel="tag">news</a>, <a href="/blog/tags/new%20committer.html" rel="tag">new committer</a></p>
+    </div>
+  </div>
+</div>
+
+    
+  
+    
+      <div class="post">
+  
     <h2><a href="/blog/2019/05/30/libcloud-2-5-0-released.html">Libcloud 2.5.0 released</a></h2>
   
 
@@ -372,105 +434,6 @@ list of people who contributed to this r
 
     
   
-    
-      <div class="post">
-  
-    <h2><a href="/blog/2017/12/30/libcloud-year-in-review-2017-released.html">Libcloud Year in Review 2017</a></h2>
-  
-
-  
-    
-  
-  <span class="post-date-author">By Tomaz Muraus <span style="display:none">(<a href="https://plus.google.com/+TomazMuraus?rel=author">Google+</a>)</span>on Dec 30, 2017</span>
-
-  <div class="post-content">
-    <p>Another year is behind us. Like most of the previous years, this year included
-a lot of exciting development. This post is going to present some statistics and
-highlights of the year.</p>
-
-<h3>Year in Numbers (recap)</h3>
-
-<ul>
-<li>800+ commits</li>
-<li>191 opened PRs on Github (159 closed, 32 open at the time of this writing)</li>
-<li>86 opened JIRA issues</li>
-<li>75+ different contributors</li>
-<li>4 releases (3 major ones)</li>
-</ul>
-
-<div class="imginline">
-  <a href="https://www.openhub.net/p/libcloud" target="_blank"><img src="/images/posts/2017-12-30-libcloud-year-in-review-2017-released/Screenshot from 2017-12-29 19-07-48.png" class="img-responsive inline" /></a>
-  <p class="img-caption">Statistics from Open Hub.</p>
-</div>
-
-<p>You can also dig into the numbers yourself on <a href="https://github.com/apache/libcloud/pulse">Github</a>, <a href="https://www.openhub.net/p/libcloud">Open Hub</a> and
-<a href="https://projects.apache.org/project.html?libcloud">Apache Project Information</a>.</p>
-
-<h2>Releases</h2>
-
-<p>This year we had 4 releases (2.0.0, 2.1.0, 2.2.0, 2.2.1). Out of that, three
-major ones.</p>
-
-<p>Libcloud 2.0.0 which was released in April represented a big milestone. We
-finally moved away from our home grown HTTP abstraction layer built on top
-of Python&#39;s httplib library to the popular requests library.</p>
-
-<p>Back in the day when the project started, requests library didn&#39;t exist yet so
-we needed to build a lot of the functionality which is now provided by requests
-ourselves. Move to requests means that we now have a lot less code to maintain
-and we can focus our efforts on the actual drivers which is core to Libcloud and
-where the project provides value.</p>
-
-<p>To give you an idea how much effort it took - the ground work for that change
-started back in 2016 (<a href="https://libcloud.apache.org/blog/2016/04/06/requests-support.html">https://libcloud.apache.org/blog/2016/04/06/requests-support.html</a>,
-<a href="https://github.com/apache/libcloud/pull/728">https://github.com/apache/libcloud/pull/728</a>), but it took a lot more testing
-and work to get it stable enough so we were finally able to include it as part
-of the stable 2.0.0 release (and before that, we also released a couple of release
-candidates so users could test and verify that their Libcloud related code
-still works as expected without any regressions).</p>
-
-<p>Special thanks to <a href="https://twitter.com/anthonypjshaw?lang=en">Anthony Shaw</a> for leading this effort and not giving up (the
-change itself involved touching a lot of code and updating test cases for most
-of the drivers which resulted in a lot of not so pleasant work and merge
-conflicts).</p>
-
-<h2>Community</h2>
-
-<p>The community continued to grow and we have received contributions from more
-than 75 different contributors. Keep in mind that this number only includes
-people who contributed a code change which has been merged into trunk. The
-actual number is quite a bit higher (code who didn&#39;t get merged, people who
-reported a bug or didn&#39;t include a code change, etc).</p>
-
-<p>We have also added one new committer - Quentin Pradet.</p>
-
-<h2>Ecosystem</h2>
-
-<p>In addition to various proprietary and private code bases, Libcloud continues
-to be used as an important part by various open-source <a href="https://pypi.python.org/pypi?%3Aaction=search&amp;term=libcloud&amp;submit=search">projects and
-libraries</a>.</p>
-
-<p>Most notable ones include <a href="https://saltstack.com/">SaltStack</a>, <a href="https://stackstorm.com/">StackStorm</a> and <a href="https://www.google.si/search?ei=bqVGWvyGMYOXkwWlgI7gCw&amp;q=ansible&amp;oq=ansible&amp;gs_l=psy-ab.3..0i67k1j0l9.2982.2982.0.3130.1.1.0.0.0.0.99.99.1.1.0....0...1c.1.64.psy-ab..0.1.99....0.4KRxU06xPjw">Ansible</a>.</p>
-
-<h2>Conclusion</h2>
-
-<p>I would like to take this opportunity to thank everyone who has contributed
-to the project in one form or another. No matter how small or involved, your
-contribution helped project grow and push through another successful year.</p>
-
-<p>Again, thank you, happy and successful 2018 and see you soon.</p>
-
-  </div>
-
-  <div class="row section post-meta">
-    <div class="col-md-12 post-tags">
-      <p>Tags: <a href="/blog/tags/news.html" rel="tag">news</a>, <a href="/blog/tags/year%20in%20review.html" rel="tag">year in review</a></p>
-    </div>
-  </div>
-</div>
-
-    
-  
 </div>
 
 <p class="navigation">
@@ -495,7 +458,7 @@ contribution helped project grow and pus
   <div class="col-lg-3 col-lg-offset-1">
     <h2>Archive</h1>
     <ul>
-      <li> <a href="/blog/archives/2021/01/"> January 2021</a> &nbsp;(1)</li><li> <a href="/blog/archives/2020/09/"> September 2020</a> &nbsp;(1)</li><li> <a href="/blog/archives/2020/08/"> August 2020</a> &nbsp;(2)</li><li> <a href="/blog/archives/2020/06/"> June 2020</a> &nbsp;(2)</li><li> <a href="/blog/archives/2020/04/"> April 2020</a> &nbsp;(2)</li><li> <a href="/blog/archives/2020/03/"> March 2020</a> &nbsp;(1)</li><li> <a href="/blog/archives/2020/01/"> January 2020</a> &nbsp;(2)</li><li> <a href="/blog/archives/2019/12/"> December 2019</a> &nbsp;(1)</li><li> <a href="/blog/archives/2019/11/"> November 2019</a> &nbsp;(1)</li><li> <a href="/blog/archives/2019/08/"> August 2019</a> &nbsp;(2)</li><li> <a href="/blog/archives/2019/05/"> May 2019</a> &nbsp;(1)</li><li> <a href="/blog/archives/2018/11/"> November 2018</a> &nbsp;(1)</li><li> <a href="/blog/archives/2018/06/"> June 2018</a> &nbsp;(1)</li><li> <a href="/blog/archives/2018/03/"> March 2018</a> &nbsp;(1)</li><li> <a hr
 ef="/blog/archives/2017/12/"> December 2017</a> &nbsp;(1)</li><li> <a href="/blog/archives/2017/09/"> September 2017</a> &nbsp;(2)</li><li> <a href="/blog/archives/2017/07/"> July 2017</a> &nbsp;(1)</li><li> <a href="/blog/archives/2017/04/"> April 2017</a> &nbsp;(3)</li><li> <a href="/blog/archives/2016/12/"> December 2016</a> &nbsp;(1)</li><li> <a href="/blog/archives/2016/11/"> November 2016</a> &nbsp;(1)</li><li> <a href="/blog/archives/2016/10/"> October 2016</a> &nbsp;(1)</li><li> <a href="/blog/archives/2016/09/"> September 2016</a> &nbsp;(1)</li><li> <a href="/blog/archives/2016/07/"> July 2016</a> &nbsp;(1)</li><li> <a href="/blog/archives/2016/06/"> June 2016</a> &nbsp;(1)</li><li> <a href="/blog/archives/2016/04/"> April 2016</a> &nbsp;(2)</li><li> <a href="/blog/archives/2016/02/"> February 2016</a> &nbsp;(2)</li><li> <a href="/blog/archives/2016/01/"> January 2016</a> &nbsp;(4)</li><li> <a href="/blog/archives/2015/12/"> December 2015</a> &nbsp;(1)</li><li> <a href="/bl
 og/archives/2015/11/"> November 2015</a> &nbsp;(1)</li><li> <a href="/blog/archives/2015/10/"> October 2015</a> &nbsp;(2)</li><li> <a href="/blog/archives/2015/08/"> August 2015</a> &nbsp;(1)</li><li> <a href="/blog/archives/2015/03/"> March 2015</a> &nbsp;(1)</li><li> <a href="/blog/archives/2015/02/"> February 2015</a> &nbsp;(1)</li><li> <a href="/blog/archives/2014/12/"> December 2014</a> &nbsp;(1)</li><li> <a href="/blog/archives/2014/11/"> November 2014</a> &nbsp;(1)</li><li> <a href="/blog/archives/2014/07/"> July 2014</a> &nbsp;(2)</li><li> <a href="/blog/archives/2014/06/"> June 2014</a> &nbsp;(1)</li><li> <a href="/blog/archives/2014/05/"> May 2014</a> &nbsp;(1)</li><li> <a href="/blog/archives/2014/04/"> April 2014</a> &nbsp;(1)</li><li> <a href="/blog/archives/2014/02/"> February 2014</a> &nbsp;(8)</li><li> <a href="/blog/archives/2014/01/"> January 2014</a> &nbsp;(4)</li><li> <a href="/blog/archives/2013/12/"> December 2013</a> &nbsp;(3)</li><li> <a href="/blog/archives/
 2013/11/"> November 2013</a> &nbsp;(2)</li><li> <a href="/blog/archives/2013/09/"> September 2013</a> &nbsp;(1)</li><li> <a href="/blog/archives/2013/08/"> August 2013</a> &nbsp;(1)</li><li> <a href="/blog/archives/2013/07/"> July 2013</a> &nbsp;(1)</li><li> <a href="/blog/archives/2013/03/"> March 2013</a> &nbsp;(1)</li><li> <a href="/blog/archives/2013/02/"> February 2013</a> &nbsp;(1)</li><li> <a href="/blog/archives/2012/12/"> December 2012</a> &nbsp;(2)</li><li> <a href="/blog/archives/2012/11/"> November 2012</a> &nbsp;(2)</li><li> <a href="/blog/archives/2012/09/"> September 2012</a> &nbsp;(1)</li><li> <a href="/blog/archives/2012/08/"> August 2012</a> &nbsp;(1)</li><li> <a href="/blog/archives/2012/07/"> July 2012</a> &nbsp;(1)</li><li> <a href="/blog/archives/2012/05/"> May 2012</a> &nbsp;(2)</li><li> <a href="/blog/archives/2012/04/"> April 2012</a> &nbsp;(1)</li><li> <a href="/blog/archives/2012/02/"> February 2012</a> &nbsp;(1)</li><li> <a href="/blog/archives/2011/12/">
  December 2011</a> &nbsp;(2)</li><li> <a href="/blog/archives/2011/11/"> November 2011</a> &nbsp;(3)</li><li> <a href="/blog/archives/2011/10/"> October 2011</a> &nbsp;(1)</li><li> <a href="/blog/archives/2011/09/"> September 2011</a> &nbsp;(1)</li><li> <a href="/blog/archives/2011/07/"> July 2011</a> &nbsp;(1)</li><li> <a href="/blog/archives/2011/06/"> June 2011</a> &nbsp;(1)</li><li> <a href="/blog/archives/2011/05/"> May 2011</a> &nbsp;(1)</li><li> <a href="/blog/archives/2011/02/"> February 2011</a> &nbsp;(1)</li><li> <a href="/blog/archives/2011/01/"> January 2011</a> &nbsp;(1)</li><li> <a href="/blog/archives/2010/10/"> October 2010</a> &nbsp;(1)</li><li> <a href="/blog/archives/2010/05/"> May 2010</a> &nbsp;(1)</li><li> <a href="/blog/archives/2010/02/"> February 2010</a> &nbsp;(1)</li>
+      <li> <a href="/blog/archives/2021/01/"> January 2021</a> &nbsp;(2)</li><li> <a href="/blog/archives/2020/09/"> September 2020</a> &nbsp;(1)</li><li> <a href="/blog/archives/2020/08/"> August 2020</a> &nbsp;(2)</li><li> <a href="/blog/archives/2020/06/"> June 2020</a> &nbsp;(2)</li><li> <a href="/blog/archives/2020/04/"> April 2020</a> &nbsp;(2)</li><li> <a href="/blog/archives/2020/03/"> March 2020</a> &nbsp;(1)</li><li> <a href="/blog/archives/2020/01/"> January 2020</a> &nbsp;(2)</li><li> <a href="/blog/archives/2019/12/"> December 2019</a> &nbsp;(1)</li><li> <a href="/blog/archives/2019/11/"> November 2019</a> &nbsp;(1)</li><li> <a href="/blog/archives/2019/08/"> August 2019</a> &nbsp;(2)</li><li> <a href="/blog/archives/2019/05/"> May 2019</a> &nbsp;(1)</li><li> <a href="/blog/archives/2018/11/"> November 2018</a> &nbsp;(1)</li><li> <a href="/blog/archives/2018/06/"> June 2018</a> &nbsp;(1)</li><li> <a href="/blog/archives/2018/03/"> March 2018</a> &nbsp;(1)</li><li> <a hr
 ef="/blog/archives/2017/12/"> December 2017</a> &nbsp;(1)</li><li> <a href="/blog/archives/2017/09/"> September 2017</a> &nbsp;(2)</li><li> <a href="/blog/archives/2017/07/"> July 2017</a> &nbsp;(1)</li><li> <a href="/blog/archives/2017/04/"> April 2017</a> &nbsp;(3)</li><li> <a href="/blog/archives/2016/12/"> December 2016</a> &nbsp;(1)</li><li> <a href="/blog/archives/2016/11/"> November 2016</a> &nbsp;(1)</li><li> <a href="/blog/archives/2016/10/"> October 2016</a> &nbsp;(1)</li><li> <a href="/blog/archives/2016/09/"> September 2016</a> &nbsp;(1)</li><li> <a href="/blog/archives/2016/07/"> July 2016</a> &nbsp;(1)</li><li> <a href="/blog/archives/2016/06/"> June 2016</a> &nbsp;(1)</li><li> <a href="/blog/archives/2016/04/"> April 2016</a> &nbsp;(2)</li><li> <a href="/blog/archives/2016/02/"> February 2016</a> &nbsp;(2)</li><li> <a href="/blog/archives/2016/01/"> January 2016</a> &nbsp;(4)</li><li> <a href="/blog/archives/2015/12/"> December 2015</a> &nbsp;(1)</li><li> <a href="/bl
 og/archives/2015/11/"> November 2015</a> &nbsp;(1)</li><li> <a href="/blog/archives/2015/10/"> October 2015</a> &nbsp;(2)</li><li> <a href="/blog/archives/2015/08/"> August 2015</a> &nbsp;(1)</li><li> <a href="/blog/archives/2015/03/"> March 2015</a> &nbsp;(1)</li><li> <a href="/blog/archives/2015/02/"> February 2015</a> &nbsp;(1)</li><li> <a href="/blog/archives/2014/12/"> December 2014</a> &nbsp;(1)</li><li> <a href="/blog/archives/2014/11/"> November 2014</a> &nbsp;(1)</li><li> <a href="/blog/archives/2014/07/"> July 2014</a> &nbsp;(2)</li><li> <a href="/blog/archives/2014/06/"> June 2014</a> &nbsp;(1)</li><li> <a href="/blog/archives/2014/05/"> May 2014</a> &nbsp;(1)</li><li> <a href="/blog/archives/2014/04/"> April 2014</a> &nbsp;(1)</li><li> <a href="/blog/archives/2014/02/"> February 2014</a> &nbsp;(8)</li><li> <a href="/blog/archives/2014/01/"> January 2014</a> &nbsp;(4)</li><li> <a href="/blog/archives/2013/12/"> December 2013</a> &nbsp;(3)</li><li> <a href="/blog/archives/
 2013/11/"> November 2013</a> &nbsp;(2)</li><li> <a href="/blog/archives/2013/09/"> September 2013</a> &nbsp;(1)</li><li> <a href="/blog/archives/2013/08/"> August 2013</a> &nbsp;(1)</li><li> <a href="/blog/archives/2013/07/"> July 2013</a> &nbsp;(1)</li><li> <a href="/blog/archives/2013/03/"> March 2013</a> &nbsp;(1)</li><li> <a href="/blog/archives/2013/02/"> February 2013</a> &nbsp;(1)</li><li> <a href="/blog/archives/2012/12/"> December 2012</a> &nbsp;(2)</li><li> <a href="/blog/archives/2012/11/"> November 2012</a> &nbsp;(2)</li><li> <a href="/blog/archives/2012/09/"> September 2012</a> &nbsp;(1)</li><li> <a href="/blog/archives/2012/08/"> August 2012</a> &nbsp;(1)</li><li> <a href="/blog/archives/2012/07/"> July 2012</a> &nbsp;(1)</li><li> <a href="/blog/archives/2012/05/"> May 2012</a> &nbsp;(2)</li><li> <a href="/blog/archives/2012/04/"> April 2012</a> &nbsp;(1)</li><li> <a href="/blog/archives/2012/02/"> February 2012</a> &nbsp;(1)</li><li> <a href="/blog/archives/2011/12/">
  December 2011</a> &nbsp;(2)</li><li> <a href="/blog/archives/2011/11/"> November 2011</a> &nbsp;(3)</li><li> <a href="/blog/archives/2011/10/"> October 2011</a> &nbsp;(1)</li><li> <a href="/blog/archives/2011/09/"> September 2011</a> &nbsp;(1)</li><li> <a href="/blog/archives/2011/07/"> July 2011</a> &nbsp;(1)</li><li> <a href="/blog/archives/2011/06/"> June 2011</a> &nbsp;(1)</li><li> <a href="/blog/archives/2011/05/"> May 2011</a> &nbsp;(1)</li><li> <a href="/blog/archives/2011/02/"> February 2011</a> &nbsp;(1)</li><li> <a href="/blog/archives/2011/01/"> January 2011</a> &nbsp;(1)</li><li> <a href="/blog/archives/2010/10/"> October 2010</a> &nbsp;(1)</li><li> <a href="/blog/archives/2010/05/"> May 2010</a> &nbsp;(1)</li><li> <a href="/blog/archives/2010/02/"> February 2010</a> &nbsp;(1)</li>
     </ul>
   </div>
 </div>

Modified: libcloud/site/trunk/generated/blog/page/5/index.html
URL: http://svn.apache.org/viewvc/libcloud/site/trunk/generated/blog/page/5/index.html?rev=1885921&r1=1885920&r2=1885921&view=diff
==============================================================================
--- libcloud/site/trunk/generated/blog/page/5/index.html (original)
+++ libcloud/site/trunk/generated/blog/page/5/index.html Tue Jan 26 22:09:48 2021
@@ -97,6 +97,105 @@
     
       <div class="post">
   
+    <h2><a href="/blog/2017/12/30/libcloud-year-in-review-2017-released.html">Libcloud Year in Review 2017</a></h2>
+  
+
+  
+    
+  
+  <span class="post-date-author">By Tomaz Muraus <span style="display:none">(<a href="https://plus.google.com/+TomazMuraus?rel=author">Google+</a>)</span>on Dec 30, 2017</span>
+
+  <div class="post-content">
+    <p>Another year is behind us. Like most of the previous years, this year included
+a lot of exciting development. This post is going to present some statistics and
+highlights of the year.</p>
+
+<h3>Year in Numbers (recap)</h3>
+
+<ul>
+<li>800+ commits</li>
+<li>191 opened PRs on Github (159 closed, 32 open at the time of this writing)</li>
+<li>86 opened JIRA issues</li>
+<li>75+ different contributors</li>
+<li>4 releases (3 major ones)</li>
+</ul>
+
+<div class="imginline">
+  <a href="https://www.openhub.net/p/libcloud" target="_blank"><img src="/images/posts/2017-12-30-libcloud-year-in-review-2017-released/Screenshot from 2017-12-29 19-07-48.png" class="img-responsive inline" /></a>
+  <p class="img-caption">Statistics from Open Hub.</p>
+</div>
+
+<p>You can also dig into the numbers yourself on <a href="https://github.com/apache/libcloud/pulse">Github</a>, <a href="https://www.openhub.net/p/libcloud">Open Hub</a> and
+<a href="https://projects.apache.org/project.html?libcloud">Apache Project Information</a>.</p>
+
+<h2>Releases</h2>
+
+<p>This year we had 4 releases (2.0.0, 2.1.0, 2.2.0, 2.2.1). Out of that, three
+major ones.</p>
+
+<p>Libcloud 2.0.0 which was released in April represented a big milestone. We
+finally moved away from our home grown HTTP abstraction layer built on top
+of Python&#39;s httplib library to the popular requests library.</p>
+
+<p>Back in the day when the project started, requests library didn&#39;t exist yet so
+we needed to build a lot of the functionality which is now provided by requests
+ourselves. Move to requests means that we now have a lot less code to maintain
+and we can focus our efforts on the actual drivers which is core to Libcloud and
+where the project provides value.</p>
+
+<p>To give you an idea how much effort it took - the ground work for that change
+started back in 2016 (<a href="https://libcloud.apache.org/blog/2016/04/06/requests-support.html">https://libcloud.apache.org/blog/2016/04/06/requests-support.html</a>,
+<a href="https://github.com/apache/libcloud/pull/728">https://github.com/apache/libcloud/pull/728</a>), but it took a lot more testing
+and work to get it stable enough so we were finally able to include it as part
+of the stable 2.0.0 release (and before that, we also released a couple of release
+candidates so users could test and verify that their Libcloud related code
+still works as expected without any regressions).</p>
+
+<p>Special thanks to <a href="https://twitter.com/anthonypjshaw?lang=en">Anthony Shaw</a> for leading this effort and not giving up (the
+change itself involved touching a lot of code and updating test cases for most
+of the drivers which resulted in a lot of not so pleasant work and merge
+conflicts).</p>
+
+<h2>Community</h2>
+
+<p>The community continued to grow and we have received contributions from more
+than 75 different contributors. Keep in mind that this number only includes
+people who contributed a code change which has been merged into trunk. The
+actual number is quite a bit higher (code who didn&#39;t get merged, people who
+reported a bug or didn&#39;t include a code change, etc).</p>
+
+<p>We have also added one new committer - Quentin Pradet.</p>
+
+<h2>Ecosystem</h2>
+
+<p>In addition to various proprietary and private code bases, Libcloud continues
+to be used as an important part by various open-source <a href="https://pypi.python.org/pypi?%3Aaction=search&amp;term=libcloud&amp;submit=search">projects and
+libraries</a>.</p>
+
+<p>Most notable ones include <a href="https://saltstack.com/">SaltStack</a>, <a href="https://stackstorm.com/">StackStorm</a> and <a href="https://www.google.si/search?ei=bqVGWvyGMYOXkwWlgI7gCw&amp;q=ansible&amp;oq=ansible&amp;gs_l=psy-ab.3..0i67k1j0l9.2982.2982.0.3130.1.1.0.0.0.0.99.99.1.1.0....0...1c.1.64.psy-ab..0.1.99....0.4KRxU06xPjw">Ansible</a>.</p>
+
+<h2>Conclusion</h2>
+
+<p>I would like to take this opportunity to thank everyone who has contributed
+to the project in one form or another. No matter how small or involved, your
+contribution helped project grow and push through another successful year.</p>
+
+<p>Again, thank you, happy and successful 2018 and see you soon.</p>
+
+  </div>
+
+  <div class="row section post-meta">
+    <div class="col-md-12 post-tags">
+      <p>Tags: <a href="/blog/tags/news.html" rel="tag">news</a>, <a href="/blog/tags/year%20in%20review.html" rel="tag">year in review</a></p>
+    </div>
+  </div>
+</div>
+
+    
+  
+    
+      <div class="post">
+  
     <h2><a href="/blog/2017/09/21/libcloud-2-2-1-released.html">Libcloud 2.2.1 released</a></h2>
   
 
@@ -540,175 +639,6 @@ list of people who contributed to this r
 
     
   
-    
-      <div class="post">
-  
-    <h2><a href="/blog/2017/04/09/async-rfc.html">Have your say - async support in Apache Libcloud</a></h2>
-  
-
-  
-    
-  
-  <span class="post-date-author">By Anthony Shaw on Apr 09, 2017</span>
-
-  <div class="post-content">
-    <p>One of the big requests whilst we were replacing <code>httplib</code> with the <code>requests</code> package in 2.0 was why didn&#39;t
-we use a HTTP library that supports <em>asynchronous</em> API calls.</p>
-
-<p>The intention for 2.0 and replacing the HTTP backend classes was to improve the usability of the project, by making SSL
-certificates easier to manage, improving the maintainability of our source code by using an active 3rd party package and
-also improving performance and stability.</p>
-
-<p>Apache Libcloud already has documentation on threaded libraries like gevent and callback-based libraries like Twisted, see
-<a href="https://libcloud.readthedocs.io/en/latest/other/using-libcloud-in-multithreaded-and-async-environments.html">using libcloud in multithreaded environments</a>
-for examples.</p>
-
-<p><a href="https://www.python.org/dev/peps/pep-0492/#">PEP 492</a>, implemented in Python 3.5 provides a new coroutine protocol using methods,
-<code>__await__</code> for classes, a coroutine method wrapper, or a method that returns a coroutine object.
-Also async <a href="https://www.python.org/dev/peps/pep-0492/#asynchronous-iterators-and-async-for">iterators</a> and <a href="https://www.python.org/dev/peps/pep-0492/#asynchronous-context-managers-and-async-with">context managers</a>
-have been introduced.</p>
-
-<p>We would like to take advantage of the new language features by offering APIs in Apache Libcloud without breaking backward compatibility and
-compatibility for users of &lt;Python 3.5.</p>
-
-<p>Use cases for this would be:</p>
-
-<ul>
-<li>Being able to fetch <code>Node</code> or <code>StorageObject</code>s from multiple geographies or drivers simultaneously.</li>
-<li>Being able to quickly upload or download storage objects by parallelizing operations on the <code>StorageDriver</code>.</li>
-<li>Being able to call a long-running API method (e.g. generate report), whilst running other code.</li>
-</ul>
-
-<h2>Design 1 - async context managers <a href="https://github.com/apache/libcloud/pull/1016">PR 1016</a></h2>
-
-<p>This design would allow drivers to operate in 2 modes, the first is for synchronous method calls, they return list or object
-data as per usual. The second mode, API methods like <code>NodeDriver.list_nodes</code> would return a <a href="https://www.python.org/dev/peps/pep-0492/#coroutine-objects">coroutine object</a>
-and could be awaited or gathered using an event loop.</p>
-
-<div class="highlight"><pre><code class="python language-python" data-lang="python"><span class="kn">import</span> <span class="nn">asyncio</span>
-
-<span class="kn">from</span> <span class="nn">integration.driver.test</span> <span class="kn">import</span> <span class="n">TestNodeDriver</span>
-<span class="kn">from</span> <span class="nn">libcloud.async_util</span> <span class="kn">import</span> <span class="n">AsyncSession</span>
-
-<span class="n">driver</span> <span class="o">=</span> <span class="n">TestNodeDriver</span><span class="p">(</span><span class="s">&#39;apache&#39;</span><span class="p">,</span> <span class="s">&#39;libcloud&#39;</span><span class="p">)</span>
-
-<span class="n">async</span> <span class="k">def</span> <span class="nf">run</span><span class="p">():</span>
-    <span class="c"># regular API call</span>
-    <span class="n">nodes</span> <span class="o">=</span> <span class="n">driver</span><span class="o">.</span><span class="n">list_nodes</span><span class="p">()</span>
-
-    <span class="n">async</span> <span class="k">with</span> <span class="n">AsyncSession</span><span class="p">(</span><span class="n">driver</span><span class="p">)</span> <span class="k">as</span> <span class="n">async_instance</span><span class="p">:</span>
-        <span class="n">nodes</span> <span class="o">=</span> <span class="n">await</span> <span class="n">async_instance</span><span class="o">.</span><span class="n">list_nodes</span><span class="p">()</span>
-
-    <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="n">nodes</span><span class="p">)</span> <span class="o">==</span> <span class="mi">2</span>
-
-<span class="n">loop</span> <span class="o">=</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">get_event_loop</span><span class="p">()</span>
-<span class="n">loop</span><span class="o">.</span><span class="n">run_until_complete</span><span class="p">(</span><span class="n">run</span><span class="p">())</span>
-<span class="n">loop</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
-</code></pre></div>
-
-<h2>Design 2 - Additional methods in each driver for coroutines <a href="https://github.com/apache/libcloud/pull/1027">PR 1027</a></h2>
-
-<p>This is the second design concept for async support in Libcloud.</p>
-
-<p>The concept here is to have Asynchronous Mixins, <code>LibcloudConnection</code> uses requests and <code>LibcloudAsyncConnection</code> uses aiohttp for async transport <a href="https://github.com/tonybaloney/libcloud/blob/d4fe097476d2f02941e17d5e1b1d405fcf44c0f7/libcloud/connection_async.py#L22-L42">see</a></p>
-
-<p>The LibcloudAsyncConnection is an implementation detail of AsyncConnection, which is the API for the drivers to consume <a href="https://github.com/tonybaloney/libcloud/blob/d4fe097476d2f02941e17d5e1b1d405fcf44c0f7/libcloud/common/base.py#L742-L778">see</a></p>
-
-<p>The drivers then use this mixin for their custom connection classes, e.g.</p>
-
-<div class="highlight"><pre><code class="python language-python" data-lang="python"><span class="k">class</span> <span class="nc">GoogleStorageConnection</span><span class="p">(</span><span class="n">ConnectionUserAndKey</span><span class="p">,</span> <span class="n">AsyncConnection</span><span class="p">):</span>
-    <span class="o">...</span>
-</code></pre></div>
-
-<p>They then inherit from <code>libcloud.storage.base.StorageAsyncDriver</code>, which uses a new set of base methods, e.g. <code>iterate_containers_async</code> and can be implemented like this:</p>
-
-<div class="highlight"><pre><code class="python language-python" data-lang="python">        <span class="n">async</span> <span class="k">def</span> <span class="nf">iterate_containers_async</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
-            <span class="n">response</span> <span class="o">=</span> <span class="n">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">connection</span><span class="o">.</span><span class="n">request_async</span><span class="p">(</span><span class="s">&#39;/&#39;</span><span class="p">)</span>
-            <span class="k">if</span> <span class="n">response</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="n">httplib</span><span class="o">.</span><span class="n">OK</span><span class="p">:</span>
-                <span class="n">containers</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_to_containers</span><span class="p">(</span><span class="n">obj</span><span class="o">=</span><span class="n">response</span><span class="o">.</span><span class="n">object</span><span class="p">,</span>
-                                                 <span class="n">xpath</span><span class="o">=</span><span class="s">&#39;Buckets/Bucket&#39;</span><span class="p">)</span>
-                <span class="k">return</span> <span class="n">containers</span>
-
-            <span class="k">raise</span> <span class="n">LibcloudError</span><span class="p">(</span><span class="s">&#39;Unexpected status code: </span><span class="si">%s</span><span class="s">&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">status</span><span class="p">),</span>
-                                <span class="n">driver</span><span class="o">=</span><span class="bp">self</span><span class="p">)</span>
-</code></pre></div>
-
-<p>Now the consumer can more or less do this:</p>
-
-<div class="highlight"><pre><code class="python language-python" data-lang="python"><span class="kn">from</span> <span class="nn">libcloud.storage.providers</span> <span class="kn">import</span> <span class="n">get_driver</span>
-<span class="kn">from</span> <span class="nn">libcloud.storage.types</span> <span class="kn">import</span> <span class="n">Provider</span>
-
-<span class="kn">import</span> <span class="nn">asyncio</span>
-
-<span class="n">GoogleStorageDriver</span> <span class="o">=</span> <span class="n">get_driver</span><span class="p">(</span><span class="n">Provider</span><span class="o">.</span><span class="n">GOOGLE_STORAGE</span><span class="p">)</span>
-<span class="n">driver</span> <span class="o">=</span> <span class="n">GoogleStorageDriver</span><span class="p">(</span><span class="n">key</span><span class="o">=</span><span class="n">KEY</span><span class="p">,</span> <span class="n">secret</span><span class="o">=</span><span class="n">SECRET</span><span class="p">)</span>
-
-<span class="k">def</span> <span class="nf">do_stuff_with_object</span><span class="p">(</span><span class="n">obj</span><span class="p">):</span>
-    <span class="k">print</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span>
-
-<span class="n">async</span> <span class="k">def</span> <span class="nf">run</span><span class="p">():</span>
-    <span class="n">tasks</span> <span class="o">=</span> <span class="p">[]</span>
-    <span class="n">async</span> <span class="k">for</span> <span class="n">container</span> <span class="ow">in</span> <span class="n">driver</span><span class="o">.</span><span class="n">iterate_containers_async</span><span class="p">():</span>
-        <span class="n">async</span> <span class="k">for</span> <span class="n">obj</span> <span class="ow">in</span> <span class="n">driver</span><span class="o">.</span><span class="n">iterate_container_objects_async</span><span class="p">(</span><span class="n">container</span><span class="p">):</span>
-            <span class="n">tasks</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">asyncio</span><span class="o">.</span><span class="n">ensure_future</span><span class="p">(</span><span class="n">do_stuff_with_object</span><span class="p">(</span><span class="n">obj</span><span class="p">)))</span>
-    <span class="n">await</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">gather</span><span class="p">(</span><span class="o">*</span><span class="n">tasks</span><span class="p">)</span>
-
-<span class="n">loop</span> <span class="o">=</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">get_event_loop</span><span class="p">()</span>
-<span class="n">loop</span><span class="o">.</span><span class="n">run_until_complete</span><span class="p">(</span><span class="n">run</span><span class="p">())</span>
-<span class="n">loop</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
-</code></pre></div>
-
-<h2>Design 3 - Initializer with &quot;<em>async</em>&quot; mode</h2>
-
-<p>This option is similar to 2, except that if a driver is instantiated with &quot;<code>async=True</code>&quot;,
-then all driver class methods would return coroutine objects. Internally, it would
-patch the Connection class with the AsyncConnection class.</p>
-
-<p>The downside of this is that all method calls to a driver would need to be awaited or used
-by an event loop.</p>
-
-<div class="highlight"><pre><code class="python language-python" data-lang="python"><span class="kn">from</span> <span class="nn">libcloud.storage.providers</span> <span class="kn">import</span> <span class="n">get_driver</span>
-<span class="kn">from</span> <span class="nn">libcloud.storage.types</span> <span class="kn">import</span> <span class="n">Provider</span>
-
-<span class="kn">import</span> <span class="nn">asyncio</span>
-
-<span class="n">GoogleStorageDriver</span> <span class="o">=</span> <span class="n">get_driver</span><span class="p">(</span><span class="n">Provider</span><span class="o">.</span><span class="n">GOOGLE_STORAGE</span><span class="p">)</span>
-<span class="n">driver</span> <span class="o">=</span> <span class="n">GoogleStorageDriver</span><span class="p">(</span><span class="n">key</span><span class="o">=</span><span class="n">KEY</span><span class="p">,</span> <span class="n">secret</span><span class="o">=</span><span class="n">SECRET</span><span class="p">,</span> <span class="n">async</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
-
-<span class="k">def</span> <span class="nf">do_stuff_with_object</span><span class="p">(</span><span class="n">obj</span><span class="p">):</span>
-    <span class="k">print</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span>
-
-<span class="n">async</span> <span class="k">def</span> <span class="nf">run</span><span class="p">():</span>
-    <span class="n">tasks</span> <span class="o">=</span> <span class="p">[]</span>
-    <span class="n">async</span> <span class="k">for</span> <span class="n">container</span> <span class="ow">in</span> <span class="n">driver</span><span class="o">.</span><span class="n">iterate_containers</span><span class="p">():</span>
-        <span class="n">async</span> <span class="k">for</span> <span class="n">obj</span> <span class="ow">in</span> <span class="n">driver</span><span class="o">.</span><span class="n">iterate_container_objects</span><span class="p">(</span><span class="n">container</span><span class="p">):</span>
-            <span class="n">tasks</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">asyncio</span><span class="o">.</span><span class="n">ensure_future</span><span class="p">(</span><span class="n">do_stuff_with_object</span><span class="p">(</span><span class="n">obj</span><span class="p">)))</span>
-    <span class="n">await</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">gather</span><span class="p">(</span><span class="o">*</span><span class="n">tasks</span><span class="p">)</span>
-
-<span class="n">loop</span> <span class="o">=</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">get_event_loop</span><span class="p">()</span>
-<span class="n">loop</span><span class="o">.</span><span class="n">run_until_complete</span><span class="p">(</span><span class="n">run</span><span class="p">())</span>
-<span class="n">loop</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
-</code></pre></div>
-
-<h1>Give us feedback</h1>
-
-<p>Got a better idea? Have an API or design, the question we&#39;re asking is 
-&quot;if you wanted to use Libcloud for an async application, what would the code look like?&quot; This helps us design
-the API and the implementation details can follow.</p>
-
-<p>Feel free to comment on the mailing list or on the pull requests, or raise your own pull-request with an API design.</p>
-
-  </div>
-
-  <div class="row section post-meta">
-    <div class="col-md-12 post-tags">
-      <p>Tags: <a href="/blog/tags/news.html" rel="tag">news</a>, <a href="/blog/tags/tutorial.html" rel="tag">tutorial</a></p>
-    </div>
-  </div>
-</div>
-
-    
-  
 </div>
 
 <p class="navigation">
@@ -733,7 +663,7 @@ the API and the implementation details c
   <div class="col-lg-3 col-lg-offset-1">
     <h2>Archive</h1>
     <ul>
-      <li> <a href="/blog/archives/2021/01/"> January 2021</a> &nbsp;(1)</li><li> <a href="/blog/archives/2020/09/"> September 2020</a> &nbsp;(1)</li><li> <a href="/blog/archives/2020/08/"> August 2020</a> &nbsp;(2)</li><li> <a href="/blog/archives/2020/06/"> June 2020</a> &nbsp;(2)</li><li> <a href="/blog/archives/2020/04/"> April 2020</a> &nbsp;(2)</li><li> <a href="/blog/archives/2020/03/"> March 2020</a> &nbsp;(1)</li><li> <a href="/blog/archives/2020/01/"> January 2020</a> &nbsp;(2)</li><li> <a href="/blog/archives/2019/12/"> December 2019</a> &nbsp;(1)</li><li> <a href="/blog/archives/2019/11/"> November 2019</a> &nbsp;(1)</li><li> <a href="/blog/archives/2019/08/"> August 2019</a> &nbsp;(2)</li><li> <a href="/blog/archives/2019/05/"> May 2019</a> &nbsp;(1)</li><li> <a href="/blog/archives/2018/11/"> November 2018</a> &nbsp;(1)</li><li> <a href="/blog/archives/2018/06/"> June 2018</a> &nbsp;(1)</li><li> <a href="/blog/archives/2018/03/"> March 2018</a> &nbsp;(1)</li><li> <a hr
 ef="/blog/archives/2017/12/"> December 2017</a> &nbsp;(1)</li><li> <a href="/blog/archives/2017/09/"> September 2017</a> &nbsp;(2)</li><li> <a href="/blog/archives/2017/07/"> July 2017</a> &nbsp;(1)</li><li> <a href="/blog/archives/2017/04/"> April 2017</a> &nbsp;(3)</li><li> <a href="/blog/archives/2016/12/"> December 2016</a> &nbsp;(1)</li><li> <a href="/blog/archives/2016/11/"> November 2016</a> &nbsp;(1)</li><li> <a href="/blog/archives/2016/10/"> October 2016</a> &nbsp;(1)</li><li> <a href="/blog/archives/2016/09/"> September 2016</a> &nbsp;(1)</li><li> <a href="/blog/archives/2016/07/"> July 2016</a> &nbsp;(1)</li><li> <a href="/blog/archives/2016/06/"> June 2016</a> &nbsp;(1)</li><li> <a href="/blog/archives/2016/04/"> April 2016</a> &nbsp;(2)</li><li> <a href="/blog/archives/2016/02/"> February 2016</a> &nbsp;(2)</li><li> <a href="/blog/archives/2016/01/"> January 2016</a> &nbsp;(4)</li><li> <a href="/blog/archives/2015/12/"> December 2015</a> &nbsp;(1)</li><li> <a href="/bl
 og/archives/2015/11/"> November 2015</a> &nbsp;(1)</li><li> <a href="/blog/archives/2015/10/"> October 2015</a> &nbsp;(2)</li><li> <a href="/blog/archives/2015/08/"> August 2015</a> &nbsp;(1)</li><li> <a href="/blog/archives/2015/03/"> March 2015</a> &nbsp;(1)</li><li> <a href="/blog/archives/2015/02/"> February 2015</a> &nbsp;(1)</li><li> <a href="/blog/archives/2014/12/"> December 2014</a> &nbsp;(1)</li><li> <a href="/blog/archives/2014/11/"> November 2014</a> &nbsp;(1)</li><li> <a href="/blog/archives/2014/07/"> July 2014</a> &nbsp;(2)</li><li> <a href="/blog/archives/2014/06/"> June 2014</a> &nbsp;(1)</li><li> <a href="/blog/archives/2014/05/"> May 2014</a> &nbsp;(1)</li><li> <a href="/blog/archives/2014/04/"> April 2014</a> &nbsp;(1)</li><li> <a href="/blog/archives/2014/02/"> February 2014</a> &nbsp;(8)</li><li> <a href="/blog/archives/2014/01/"> January 2014</a> &nbsp;(4)</li><li> <a href="/blog/archives/2013/12/"> December 2013</a> &nbsp;(3)</li><li> <a href="/blog/archives/
 2013/11/"> November 2013</a> &nbsp;(2)</li><li> <a href="/blog/archives/2013/09/"> September 2013</a> &nbsp;(1)</li><li> <a href="/blog/archives/2013/08/"> August 2013</a> &nbsp;(1)</li><li> <a href="/blog/archives/2013/07/"> July 2013</a> &nbsp;(1)</li><li> <a href="/blog/archives/2013/03/"> March 2013</a> &nbsp;(1)</li><li> <a href="/blog/archives/2013/02/"> February 2013</a> &nbsp;(1)</li><li> <a href="/blog/archives/2012/12/"> December 2012</a> &nbsp;(2)</li><li> <a href="/blog/archives/2012/11/"> November 2012</a> &nbsp;(2)</li><li> <a href="/blog/archives/2012/09/"> September 2012</a> &nbsp;(1)</li><li> <a href="/blog/archives/2012/08/"> August 2012</a> &nbsp;(1)</li><li> <a href="/blog/archives/2012/07/"> July 2012</a> &nbsp;(1)</li><li> <a href="/blog/archives/2012/05/"> May 2012</a> &nbsp;(2)</li><li> <a href="/blog/archives/2012/04/"> April 2012</a> &nbsp;(1)</li><li> <a href="/blog/archives/2012/02/"> February 2012</a> &nbsp;(1)</li><li> <a href="/blog/archives/2011/12/">
  December 2011</a> &nbsp;(2)</li><li> <a href="/blog/archives/2011/11/"> November 2011</a> &nbsp;(3)</li><li> <a href="/blog/archives/2011/10/"> October 2011</a> &nbsp;(1)</li><li> <a href="/blog/archives/2011/09/"> September 2011</a> &nbsp;(1)</li><li> <a href="/blog/archives/2011/07/"> July 2011</a> &nbsp;(1)</li><li> <a href="/blog/archives/2011/06/"> June 2011</a> &nbsp;(1)</li><li> <a href="/blog/archives/2011/05/"> May 2011</a> &nbsp;(1)</li><li> <a href="/blog/archives/2011/02/"> February 2011</a> &nbsp;(1)</li><li> <a href="/blog/archives/2011/01/"> January 2011</a> &nbsp;(1)</li><li> <a href="/blog/archives/2010/10/"> October 2010</a> &nbsp;(1)</li><li> <a href="/blog/archives/2010/05/"> May 2010</a> &nbsp;(1)</li><li> <a href="/blog/archives/2010/02/"> February 2010</a> &nbsp;(1)</li>
+      <li> <a href="/blog/archives/2021/01/"> January 2021</a> &nbsp;(2)</li><li> <a href="/blog/archives/2020/09/"> September 2020</a> &nbsp;(1)</li><li> <a href="/blog/archives/2020/08/"> August 2020</a> &nbsp;(2)</li><li> <a href="/blog/archives/2020/06/"> June 2020</a> &nbsp;(2)</li><li> <a href="/blog/archives/2020/04/"> April 2020</a> &nbsp;(2)</li><li> <a href="/blog/archives/2020/03/"> March 2020</a> &nbsp;(1)</li><li> <a href="/blog/archives/2020/01/"> January 2020</a> &nbsp;(2)</li><li> <a href="/blog/archives/2019/12/"> December 2019</a> &nbsp;(1)</li><li> <a href="/blog/archives/2019/11/"> November 2019</a> &nbsp;(1)</li><li> <a href="/blog/archives/2019/08/"> August 2019</a> &nbsp;(2)</li><li> <a href="/blog/archives/2019/05/"> May 2019</a> &nbsp;(1)</li><li> <a href="/blog/archives/2018/11/"> November 2018</a> &nbsp;(1)</li><li> <a href="/blog/archives/2018/06/"> June 2018</a> &nbsp;(1)</li><li> <a href="/blog/archives/2018/03/"> March 2018</a> &nbsp;(1)</li><li> <a hr
 ef="/blog/archives/2017/12/"> December 2017</a> &nbsp;(1)</li><li> <a href="/blog/archives/2017/09/"> September 2017</a> &nbsp;(2)</li><li> <a href="/blog/archives/2017/07/"> July 2017</a> &nbsp;(1)</li><li> <a href="/blog/archives/2017/04/"> April 2017</a> &nbsp;(3)</li><li> <a href="/blog/archives/2016/12/"> December 2016</a> &nbsp;(1)</li><li> <a href="/blog/archives/2016/11/"> November 2016</a> &nbsp;(1)</li><li> <a href="/blog/archives/2016/10/"> October 2016</a> &nbsp;(1)</li><li> <a href="/blog/archives/2016/09/"> September 2016</a> &nbsp;(1)</li><li> <a href="/blog/archives/2016/07/"> July 2016</a> &nbsp;(1)</li><li> <a href="/blog/archives/2016/06/"> June 2016</a> &nbsp;(1)</li><li> <a href="/blog/archives/2016/04/"> April 2016</a> &nbsp;(2)</li><li> <a href="/blog/archives/2016/02/"> February 2016</a> &nbsp;(2)</li><li> <a href="/blog/archives/2016/01/"> January 2016</a> &nbsp;(4)</li><li> <a href="/blog/archives/2015/12/"> December 2015</a> &nbsp;(1)</li><li> <a href="/bl
 og/archives/2015/11/"> November 2015</a> &nbsp;(1)</li><li> <a href="/blog/archives/2015/10/"> October 2015</a> &nbsp;(2)</li><li> <a href="/blog/archives/2015/08/"> August 2015</a> &nbsp;(1)</li><li> <a href="/blog/archives/2015/03/"> March 2015</a> &nbsp;(1)</li><li> <a href="/blog/archives/2015/02/"> February 2015</a> &nbsp;(1)</li><li> <a href="/blog/archives/2014/12/"> December 2014</a> &nbsp;(1)</li><li> <a href="/blog/archives/2014/11/"> November 2014</a> &nbsp;(1)</li><li> <a href="/blog/archives/2014/07/"> July 2014</a> &nbsp;(2)</li><li> <a href="/blog/archives/2014/06/"> June 2014</a> &nbsp;(1)</li><li> <a href="/blog/archives/2014/05/"> May 2014</a> &nbsp;(1)</li><li> <a href="/blog/archives/2014/04/"> April 2014</a> &nbsp;(1)</li><li> <a href="/blog/archives/2014/02/"> February 2014</a> &nbsp;(8)</li><li> <a href="/blog/archives/2014/01/"> January 2014</a> &nbsp;(4)</li><li> <a href="/blog/archives/2013/12/"> December 2013</a> &nbsp;(3)</li><li> <a href="/blog/archives/
 2013/11/"> November 2013</a> &nbsp;(2)</li><li> <a href="/blog/archives/2013/09/"> September 2013</a> &nbsp;(1)</li><li> <a href="/blog/archives/2013/08/"> August 2013</a> &nbsp;(1)</li><li> <a href="/blog/archives/2013/07/"> July 2013</a> &nbsp;(1)</li><li> <a href="/blog/archives/2013/03/"> March 2013</a> &nbsp;(1)</li><li> <a href="/blog/archives/2013/02/"> February 2013</a> &nbsp;(1)</li><li> <a href="/blog/archives/2012/12/"> December 2012</a> &nbsp;(2)</li><li> <a href="/blog/archives/2012/11/"> November 2012</a> &nbsp;(2)</li><li> <a href="/blog/archives/2012/09/"> September 2012</a> &nbsp;(1)</li><li> <a href="/blog/archives/2012/08/"> August 2012</a> &nbsp;(1)</li><li> <a href="/blog/archives/2012/07/"> July 2012</a> &nbsp;(1)</li><li> <a href="/blog/archives/2012/05/"> May 2012</a> &nbsp;(2)</li><li> <a href="/blog/archives/2012/04/"> April 2012</a> &nbsp;(1)</li><li> <a href="/blog/archives/2012/02/"> February 2012</a> &nbsp;(1)</li><li> <a href="/blog/archives/2011/12/">
  December 2011</a> &nbsp;(2)</li><li> <a href="/blog/archives/2011/11/"> November 2011</a> &nbsp;(3)</li><li> <a href="/blog/archives/2011/10/"> October 2011</a> &nbsp;(1)</li><li> <a href="/blog/archives/2011/09/"> September 2011</a> &nbsp;(1)</li><li> <a href="/blog/archives/2011/07/"> July 2011</a> &nbsp;(1)</li><li> <a href="/blog/archives/2011/06/"> June 2011</a> &nbsp;(1)</li><li> <a href="/blog/archives/2011/05/"> May 2011</a> &nbsp;(1)</li><li> <a href="/blog/archives/2011/02/"> February 2011</a> &nbsp;(1)</li><li> <a href="/blog/archives/2011/01/"> January 2011</a> &nbsp;(1)</li><li> <a href="/blog/archives/2010/10/"> October 2010</a> &nbsp;(1)</li><li> <a href="/blog/archives/2010/05/"> May 2010</a> &nbsp;(1)</li><li> <a href="/blog/archives/2010/02/"> February 2010</a> &nbsp;(1)</li>
     </ul>
   </div>
 </div>

Modified: libcloud/site/trunk/generated/blog/page/6/index.html
URL: http://svn.apache.org/viewvc/libcloud/site/trunk/generated/blog/page/6/index.html?rev=1885921&r1=1885920&r2=1885921&view=diff
==============================================================================
--- libcloud/site/trunk/generated/blog/page/6/index.html (original)
+++ libcloud/site/trunk/generated/blog/page/6/index.html Tue Jan 26 22:09:48 2021
@@ -97,6 +97,175 @@
     
       <div class="post">
   
+    <h2><a href="/blog/2017/04/09/async-rfc.html">Have your say - async support in Apache Libcloud</a></h2>
+  
+
+  
+    
+  
+  <span class="post-date-author">By Anthony Shaw on Apr 09, 2017</span>
+
+  <div class="post-content">
+    <p>One of the big requests whilst we were replacing <code>httplib</code> with the <code>requests</code> package in 2.0 was why didn&#39;t
+we use a HTTP library that supports <em>asynchronous</em> API calls.</p>
+
+<p>The intention for 2.0 and replacing the HTTP backend classes was to improve the usability of the project, by making SSL
+certificates easier to manage, improving the maintainability of our source code by using an active 3rd party package and
+also improving performance and stability.</p>
+
+<p>Apache Libcloud already has documentation on threaded libraries like gevent and callback-based libraries like Twisted, see
+<a href="https://libcloud.readthedocs.io/en/latest/other/using-libcloud-in-multithreaded-and-async-environments.html">using libcloud in multithreaded environments</a>
+for examples.</p>
+
+<p><a href="https://www.python.org/dev/peps/pep-0492/#">PEP 492</a>, implemented in Python 3.5 provides a new coroutine protocol using methods,
+<code>__await__</code> for classes, a coroutine method wrapper, or a method that returns a coroutine object.
+Also async <a href="https://www.python.org/dev/peps/pep-0492/#asynchronous-iterators-and-async-for">iterators</a> and <a href="https://www.python.org/dev/peps/pep-0492/#asynchronous-context-managers-and-async-with">context managers</a>
+have been introduced.</p>
+
+<p>We would like to take advantage of the new language features by offering APIs in Apache Libcloud without breaking backward compatibility and
+compatibility for users of &lt;Python 3.5.</p>
+
+<p>Use cases for this would be:</p>
+
+<ul>
+<li>Being able to fetch <code>Node</code> or <code>StorageObject</code>s from multiple geographies or drivers simultaneously.</li>
+<li>Being able to quickly upload or download storage objects by parallelizing operations on the <code>StorageDriver</code>.</li>
+<li>Being able to call a long-running API method (e.g. generate report), whilst running other code.</li>
+</ul>
+
+<h2>Design 1 - async context managers <a href="https://github.com/apache/libcloud/pull/1016">PR 1016</a></h2>
+
+<p>This design would allow drivers to operate in 2 modes, the first is for synchronous method calls, they return list or object
+data as per usual. The second mode, API methods like <code>NodeDriver.list_nodes</code> would return a <a href="https://www.python.org/dev/peps/pep-0492/#coroutine-objects">coroutine object</a>
+and could be awaited or gathered using an event loop.</p>
+
+<div class="highlight"><pre><code class="python language-python" data-lang="python"><span class="kn">import</span> <span class="nn">asyncio</span>
+
+<span class="kn">from</span> <span class="nn">integration.driver.test</span> <span class="kn">import</span> <span class="n">TestNodeDriver</span>
+<span class="kn">from</span> <span class="nn">libcloud.async_util</span> <span class="kn">import</span> <span class="n">AsyncSession</span>
+
+<span class="n">driver</span> <span class="o">=</span> <span class="n">TestNodeDriver</span><span class="p">(</span><span class="s">&#39;apache&#39;</span><span class="p">,</span> <span class="s">&#39;libcloud&#39;</span><span class="p">)</span>
+
+<span class="n">async</span> <span class="k">def</span> <span class="nf">run</span><span class="p">():</span>
+    <span class="c"># regular API call</span>
+    <span class="n">nodes</span> <span class="o">=</span> <span class="n">driver</span><span class="o">.</span><span class="n">list_nodes</span><span class="p">()</span>
+
+    <span class="n">async</span> <span class="k">with</span> <span class="n">AsyncSession</span><span class="p">(</span><span class="n">driver</span><span class="p">)</span> <span class="k">as</span> <span class="n">async_instance</span><span class="p">:</span>
+        <span class="n">nodes</span> <span class="o">=</span> <span class="n">await</span> <span class="n">async_instance</span><span class="o">.</span><span class="n">list_nodes</span><span class="p">()</span>
+
+    <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="n">nodes</span><span class="p">)</span> <span class="o">==</span> <span class="mi">2</span>
+
+<span class="n">loop</span> <span class="o">=</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">get_event_loop</span><span class="p">()</span>
+<span class="n">loop</span><span class="o">.</span><span class="n">run_until_complete</span><span class="p">(</span><span class="n">run</span><span class="p">())</span>
+<span class="n">loop</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
+</code></pre></div>
+
+<h2>Design 2 - Additional methods in each driver for coroutines <a href="https://github.com/apache/libcloud/pull/1027">PR 1027</a></h2>
+
+<p>This is the second design concept for async support in Libcloud.</p>
+
+<p>The concept here is to have Asynchronous Mixins, <code>LibcloudConnection</code> uses requests and <code>LibcloudAsyncConnection</code> uses aiohttp for async transport <a href="https://github.com/tonybaloney/libcloud/blob/d4fe097476d2f02941e17d5e1b1d405fcf44c0f7/libcloud/connection_async.py#L22-L42">see</a></p>
+
+<p>The LibcloudAsyncConnection is an implementation detail of AsyncConnection, which is the API for the drivers to consume <a href="https://github.com/tonybaloney/libcloud/blob/d4fe097476d2f02941e17d5e1b1d405fcf44c0f7/libcloud/common/base.py#L742-L778">see</a></p>
+
+<p>The drivers then use this mixin for their custom connection classes, e.g.</p>
+
+<div class="highlight"><pre><code class="python language-python" data-lang="python"><span class="k">class</span> <span class="nc">GoogleStorageConnection</span><span class="p">(</span><span class="n">ConnectionUserAndKey</span><span class="p">,</span> <span class="n">AsyncConnection</span><span class="p">):</span>
+    <span class="o">...</span>
+</code></pre></div>
+
+<p>They then inherit from <code>libcloud.storage.base.StorageAsyncDriver</code>, which uses a new set of base methods, e.g. <code>iterate_containers_async</code> and can be implemented like this:</p>
+
+<div class="highlight"><pre><code class="python language-python" data-lang="python">        <span class="n">async</span> <span class="k">def</span> <span class="nf">iterate_containers_async</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+            <span class="n">response</span> <span class="o">=</span> <span class="n">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">connection</span><span class="o">.</span><span class="n">request_async</span><span class="p">(</span><span class="s">&#39;/&#39;</span><span class="p">)</span>
+            <span class="k">if</span> <span class="n">response</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="n">httplib</span><span class="o">.</span><span class="n">OK</span><span class="p">:</span>
+                <span class="n">containers</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_to_containers</span><span class="p">(</span><span class="n">obj</span><span class="o">=</span><span class="n">response</span><span class="o">.</span><span class="n">object</span><span class="p">,</span>
+                                                 <span class="n">xpath</span><span class="o">=</span><span class="s">&#39;Buckets/Bucket&#39;</span><span class="p">)</span>
+                <span class="k">return</span> <span class="n">containers</span>
+
+            <span class="k">raise</span> <span class="n">LibcloudError</span><span class="p">(</span><span class="s">&#39;Unexpected status code: </span><span class="si">%s</span><span class="s">&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">status</span><span class="p">),</span>
+                                <span class="n">driver</span><span class="o">=</span><span class="bp">self</span><span class="p">)</span>
+</code></pre></div>
+
+<p>Now the consumer can more or less do this:</p>
+
+<div class="highlight"><pre><code class="python language-python" data-lang="python"><span class="kn">from</span> <span class="nn">libcloud.storage.providers</span> <span class="kn">import</span> <span class="n">get_driver</span>
+<span class="kn">from</span> <span class="nn">libcloud.storage.types</span> <span class="kn">import</span> <span class="n">Provider</span>
+
+<span class="kn">import</span> <span class="nn">asyncio</span>
+
+<span class="n">GoogleStorageDriver</span> <span class="o">=</span> <span class="n">get_driver</span><span class="p">(</span><span class="n">Provider</span><span class="o">.</span><span class="n">GOOGLE_STORAGE</span><span class="p">)</span>
+<span class="n">driver</span> <span class="o">=</span> <span class="n">GoogleStorageDriver</span><span class="p">(</span><span class="n">key</span><span class="o">=</span><span class="n">KEY</span><span class="p">,</span> <span class="n">secret</span><span class="o">=</span><span class="n">SECRET</span><span class="p">)</span>
+
+<span class="k">def</span> <span class="nf">do_stuff_with_object</span><span class="p">(</span><span class="n">obj</span><span class="p">):</span>
+    <span class="k">print</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span>
+
+<span class="n">async</span> <span class="k">def</span> <span class="nf">run</span><span class="p">():</span>
+    <span class="n">tasks</span> <span class="o">=</span> <span class="p">[]</span>
+    <span class="n">async</span> <span class="k">for</span> <span class="n">container</span> <span class="ow">in</span> <span class="n">driver</span><span class="o">.</span><span class="n">iterate_containers_async</span><span class="p">():</span>
+        <span class="n">async</span> <span class="k">for</span> <span class="n">obj</span> <span class="ow">in</span> <span class="n">driver</span><span class="o">.</span><span class="n">iterate_container_objects_async</span><span class="p">(</span><span class="n">container</span><span class="p">):</span>
+            <span class="n">tasks</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">asyncio</span><span class="o">.</span><span class="n">ensure_future</span><span class="p">(</span><span class="n">do_stuff_with_object</span><span class="p">(</span><span class="n">obj</span><span class="p">)))</span>
+    <span class="n">await</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">gather</span><span class="p">(</span><span class="o">*</span><span class="n">tasks</span><span class="p">)</span>
+
+<span class="n">loop</span> <span class="o">=</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">get_event_loop</span><span class="p">()</span>
+<span class="n">loop</span><span class="o">.</span><span class="n">run_until_complete</span><span class="p">(</span><span class="n">run</span><span class="p">())</span>
+<span class="n">loop</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
+</code></pre></div>
+
+<h2>Design 3 - Initializer with &quot;<em>async</em>&quot; mode</h2>
+
+<p>This option is similar to 2, except that if a driver is instantiated with &quot;<code>async=True</code>&quot;,
+then all driver class methods would return coroutine objects. Internally, it would
+patch the Connection class with the AsyncConnection class.</p>
+
+<p>The downside of this is that all method calls to a driver would need to be awaited or used
+by an event loop.</p>
+
+<div class="highlight"><pre><code class="python language-python" data-lang="python"><span class="kn">from</span> <span class="nn">libcloud.storage.providers</span> <span class="kn">import</span> <span class="n">get_driver</span>
+<span class="kn">from</span> <span class="nn">libcloud.storage.types</span> <span class="kn">import</span> <span class="n">Provider</span>
+
+<span class="kn">import</span> <span class="nn">asyncio</span>
+
+<span class="n">GoogleStorageDriver</span> <span class="o">=</span> <span class="n">get_driver</span><span class="p">(</span><span class="n">Provider</span><span class="o">.</span><span class="n">GOOGLE_STORAGE</span><span class="p">)</span>
+<span class="n">driver</span> <span class="o">=</span> <span class="n">GoogleStorageDriver</span><span class="p">(</span><span class="n">key</span><span class="o">=</span><span class="n">KEY</span><span class="p">,</span> <span class="n">secret</span><span class="o">=</span><span class="n">SECRET</span><span class="p">,</span> <span class="n">async</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
+
+<span class="k">def</span> <span class="nf">do_stuff_with_object</span><span class="p">(</span><span class="n">obj</span><span class="p">):</span>
+    <span class="k">print</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span>
+
+<span class="n">async</span> <span class="k">def</span> <span class="nf">run</span><span class="p">():</span>
+    <span class="n">tasks</span> <span class="o">=</span> <span class="p">[]</span>
+    <span class="n">async</span> <span class="k">for</span> <span class="n">container</span> <span class="ow">in</span> <span class="n">driver</span><span class="o">.</span><span class="n">iterate_containers</span><span class="p">():</span>
+        <span class="n">async</span> <span class="k">for</span> <span class="n">obj</span> <span class="ow">in</span> <span class="n">driver</span><span class="o">.</span><span class="n">iterate_container_objects</span><span class="p">(</span><span class="n">container</span><span class="p">):</span>
+            <span class="n">tasks</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">asyncio</span><span class="o">.</span><span class="n">ensure_future</span><span class="p">(</span><span class="n">do_stuff_with_object</span><span class="p">(</span><span class="n">obj</span><span class="p">)))</span>
+    <span class="n">await</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">gather</span><span class="p">(</span><span class="o">*</span><span class="n">tasks</span><span class="p">)</span>
+
+<span class="n">loop</span> <span class="o">=</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">get_event_loop</span><span class="p">()</span>
+<span class="n">loop</span><span class="o">.</span><span class="n">run_until_complete</span><span class="p">(</span><span class="n">run</span><span class="p">())</span>
+<span class="n">loop</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
+</code></pre></div>
+
+<h1>Give us feedback</h1>
+
+<p>Got a better idea? Have an API or design, the question we&#39;re asking is 
+&quot;if you wanted to use Libcloud for an async application, what would the code look like?&quot; This helps us design
+the API and the implementation details can follow.</p>
+
+<p>Feel free to comment on the mailing list or on the pull requests, or raise your own pull-request with an API design.</p>
+
+  </div>
+
+  <div class="row section post-meta">
+    <div class="col-md-12 post-tags">
+      <p>Tags: <a href="/blog/tags/news.html" rel="tag">news</a>, <a href="/blog/tags/tutorial.html" rel="tag">tutorial</a></p>
+    </div>
+  </div>
+</div>
+
+    
+  
+    
+      <div class="post">
+  
     <h2><a href="/blog/2017/04/07/libcloud-2-0-0-rc2-released.html">Libcloud 2.0.0rc2 released</a></h2>
   
 
@@ -539,142 +708,6 @@ list of people who contributed to this r
 
     
   
-    
-      <div class="post">
-  
-    <h2><a href="/blog/2016/09/23/libcloud-1-2-1-released.html">Libcloud 1.2.1 released</a></h2>
-  
-
-  
-    
-  
-  <span class="post-date-author">By Anthony Shaw on Sep 23, 2016</span>
-
-  <div class="post-content">
-    <p>We are pleased to announce the release of Libcloud 1.2.1.</p>
-
-<p>This release brings many new features, improvements, bug-fixes, and drivers.</p>
-
-<h2>Release highlights</h2>
-
-<h3>Changes in Apache Libcloud 1.2.1</h3>
-
-<ul>
-<li>Fix issue enabling backups on Dimension Data driver</li>
-</ul>
-
-<h3>Changes in Apache Libcloud 1.2.0</h3>
-
-<h4>General</h4>
-
-<ul>
-<li>Fix caching of auth tokens in the Google Compute Engine drivers. Now we make
-sure that the file is truncated before writing a new token. Not truncating the
-file would cause issues if the new token is shorted then the existing one
-which is cached in the file.</li>
-</ul>
-
-<h4>Compute</h4>
-
-<ul>
-<li>Fix image undeprecation in GCE</li>
-<li>Added Managed Instance Groups in GCE</li>
-<li>Allow undeprecation of an image in GCE</li>
-<li>BUGFIX Values with wildcards failed signature validation in cloudstack</li>
-<li>Added StorageState-Migrating to the cloudstack driver.</li>
-<li>Update copy image logic to match create image in GCE driver.</li>
-<li>Removed HD attribute from the Abiquo compute driver to support the 3.4 API</li>
-<li>Add image and size details to list_nodes response in Dimension Data driver</li>
-<li>Add support for changing VM admin password in VMware driver</li>
-<li>Add Barcelona (Spain) region to the Aurora Compute driver.</li>
-<li>Various improvements in the libvirt driver.</li>
-</ul>
-
-<h4>Load balancer</h4>
-
-<ul>
-<li>Add support for temporary IAM role credentials (token) to the AWS ELB driver.</li>
-</ul>
-
-<h4>DNS</h4>
-
-<ul>
-<li>Updated the &#39;extra&#39; parameter in update_record() to be optional in aurora driver</li>
-<li>Support for iterating over records and zones in the Aurora DNS driver</li>
-<li>Add support for DS, PTR, SSFHFP and TLSA record type to the Aurora DNS driver.</li>
-</ul>
-
-<h4>Container</h4>
-
-<ul>
-<li>Add network mode and labels when creating containers within docker driver</li>
-</ul>
-
-<h4>Storage</h4>
-
-<ul>
-<li>Fix authentication issue in S3/China region, disabled multipart uploads as
-not supported by region.</li>
-</ul>
-
-<p>Full change log can be found at <a href="https://libcloud.readthedocs.org/en/latest/changelog.html">here</a>.</p>
-
-<h3>Special thank you</h3>
-
-<p>I would like to wish a special thank you to all of our community contributors
-for their ongoing support to the project.</p>
-
-<h3>Download</h3>
-
-<p>The release can can be downloaded from
-<a href="https://libcloud.apache.org/downloads.html">https://libcloud.apache.org/downloads.html</a> or installed using pip:</p>
-
-<pre>
-pip install apache-libcloud==1.2.1
-</pre>
-
-<h3>Upgrading</h3>
-
-<p>If you have installed Libcloud using pip you can also use it to upgrade it:</p>
-
-<pre>
-pip install --upgrade apache-libcloud==1.2.1
-</pre>
-
-<h3>Upgrade notes</h3>
-
-<p>A page which describes backward incompatible or semi-incompatible
-changes and how to preserve the old behavior when this is possible
-can be found at <a href="https://libcloud.readthedocs.org/en/latest/upgrade_notes.html">https://libcloud.readthedocs.org/en/latest/upgrade_notes.html</a></p>
-
-<h3>Documentation</h3>
-
-<p>Regular and API documentation is available at <a href="https://libcloud.readthedocs.org/en/latest/">https://libcloud.readthedocs.org/en/latest/</a></p>
-
-<h3>Bugs / Issues</h3>
-
-<p>If you find any bug or issue, please report it on our issue tracker
-<a href="https://issues.apache.org/jira/browse/LIBCLOUD">https://issues.apache.org/jira/browse/LIBCLOUD</a>.
-Don&#39;t forget to attach an example and / or test which reproduces your
-problem.</p>
-
-<h3>Thanks</h3>
-
-<p>Thanks to everyone who contributed and made this release possible! Full
-list of people who contributed to this release can be found in the
-<a href="https://libcloud.readthedocs.org/en/latest/changelog.html">CHANGES file</a>.</p>
-
-  </div>
-
-  <div class="row section post-meta">
-    <div class="col-md-12 post-tags">
-      <p>Tags: <a href="/blog/tags/news.html" rel="tag">news</a>, <a href="/blog/tags/release%20announcement.html" rel="tag">release announcement</a></p>
-    </div>
-  </div>
-</div>
-
-    
-  
 </div>
 
 <p class="navigation">
@@ -699,7 +732,7 @@ list of people who contributed to this r
   <div class="col-lg-3 col-lg-offset-1">
     <h2>Archive</h1>
     <ul>
-      <li> <a href="/blog/archives/2021/01/"> January 2021</a> &nbsp;(1)</li><li> <a href="/blog/archives/2020/09/"> September 2020</a> &nbsp;(1)</li><li> <a href="/blog/archives/2020/08/"> August 2020</a> &nbsp;(2)</li><li> <a href="/blog/archives/2020/06/"> June 2020</a> &nbsp;(2)</li><li> <a href="/blog/archives/2020/04/"> April 2020</a> &nbsp;(2)</li><li> <a href="/blog/archives/2020/03/"> March 2020</a> &nbsp;(1)</li><li> <a href="/blog/archives/2020/01/"> January 2020</a> &nbsp;(2)</li><li> <a href="/blog/archives/2019/12/"> December 2019</a> &nbsp;(1)</li><li> <a href="/blog/archives/2019/11/"> November 2019</a> &nbsp;(1)</li><li> <a href="/blog/archives/2019/08/"> August 2019</a> &nbsp;(2)</li><li> <a href="/blog/archives/2019/05/"> May 2019</a> &nbsp;(1)</li><li> <a href="/blog/archives/2018/11/"> November 2018</a> &nbsp;(1)</li><li> <a href="/blog/archives/2018/06/"> June 2018</a> &nbsp;(1)</li><li> <a href="/blog/archives/2018/03/"> March 2018</a> &nbsp;(1)</li><li> <a hr
 ef="/blog/archives/2017/12/"> December 2017</a> &nbsp;(1)</li><li> <a href="/blog/archives/2017/09/"> September 2017</a> &nbsp;(2)</li><li> <a href="/blog/archives/2017/07/"> July 2017</a> &nbsp;(1)</li><li> <a href="/blog/archives/2017/04/"> April 2017</a> &nbsp;(3)</li><li> <a href="/blog/archives/2016/12/"> December 2016</a> &nbsp;(1)</li><li> <a href="/blog/archives/2016/11/"> November 2016</a> &nbsp;(1)</li><li> <a href="/blog/archives/2016/10/"> October 2016</a> &nbsp;(1)</li><li> <a href="/blog/archives/2016/09/"> September 2016</a> &nbsp;(1)</li><li> <a href="/blog/archives/2016/07/"> July 2016</a> &nbsp;(1)</li><li> <a href="/blog/archives/2016/06/"> June 2016</a> &nbsp;(1)</li><li> <a href="/blog/archives/2016/04/"> April 2016</a> &nbsp;(2)</li><li> <a href="/blog/archives/2016/02/"> February 2016</a> &nbsp;(2)</li><li> <a href="/blog/archives/2016/01/"> January 2016</a> &nbsp;(4)</li><li> <a href="/blog/archives/2015/12/"> December 2015</a> &nbsp;(1)</li><li> <a href="/bl
 og/archives/2015/11/"> November 2015</a> &nbsp;(1)</li><li> <a href="/blog/archives/2015/10/"> October 2015</a> &nbsp;(2)</li><li> <a href="/blog/archives/2015/08/"> August 2015</a> &nbsp;(1)</li><li> <a href="/blog/archives/2015/03/"> March 2015</a> &nbsp;(1)</li><li> <a href="/blog/archives/2015/02/"> February 2015</a> &nbsp;(1)</li><li> <a href="/blog/archives/2014/12/"> December 2014</a> &nbsp;(1)</li><li> <a href="/blog/archives/2014/11/"> November 2014</a> &nbsp;(1)</li><li> <a href="/blog/archives/2014/07/"> July 2014</a> &nbsp;(2)</li><li> <a href="/blog/archives/2014/06/"> June 2014</a> &nbsp;(1)</li><li> <a href="/blog/archives/2014/05/"> May 2014</a> &nbsp;(1)</li><li> <a href="/blog/archives/2014/04/"> April 2014</a> &nbsp;(1)</li><li> <a href="/blog/archives/2014/02/"> February 2014</a> &nbsp;(8)</li><li> <a href="/blog/archives/2014/01/"> January 2014</a> &nbsp;(4)</li><li> <a href="/blog/archives/2013/12/"> December 2013</a> &nbsp;(3)</li><li> <a href="/blog/archives/
 2013/11/"> November 2013</a> &nbsp;(2)</li><li> <a href="/blog/archives/2013/09/"> September 2013</a> &nbsp;(1)</li><li> <a href="/blog/archives/2013/08/"> August 2013</a> &nbsp;(1)</li><li> <a href="/blog/archives/2013/07/"> July 2013</a> &nbsp;(1)</li><li> <a href="/blog/archives/2013/03/"> March 2013</a> &nbsp;(1)</li><li> <a href="/blog/archives/2013/02/"> February 2013</a> &nbsp;(1)</li><li> <a href="/blog/archives/2012/12/"> December 2012</a> &nbsp;(2)</li><li> <a href="/blog/archives/2012/11/"> November 2012</a> &nbsp;(2)</li><li> <a href="/blog/archives/2012/09/"> September 2012</a> &nbsp;(1)</li><li> <a href="/blog/archives/2012/08/"> August 2012</a> &nbsp;(1)</li><li> <a href="/blog/archives/2012/07/"> July 2012</a> &nbsp;(1)</li><li> <a href="/blog/archives/2012/05/"> May 2012</a> &nbsp;(2)</li><li> <a href="/blog/archives/2012/04/"> April 2012</a> &nbsp;(1)</li><li> <a href="/blog/archives/2012/02/"> February 2012</a> &nbsp;(1)</li><li> <a href="/blog/archives/2011/12/">
  December 2011</a> &nbsp;(2)</li><li> <a href="/blog/archives/2011/11/"> November 2011</a> &nbsp;(3)</li><li> <a href="/blog/archives/2011/10/"> October 2011</a> &nbsp;(1)</li><li> <a href="/blog/archives/2011/09/"> September 2011</a> &nbsp;(1)</li><li> <a href="/blog/archives/2011/07/"> July 2011</a> &nbsp;(1)</li><li> <a href="/blog/archives/2011/06/"> June 2011</a> &nbsp;(1)</li><li> <a href="/blog/archives/2011/05/"> May 2011</a> &nbsp;(1)</li><li> <a href="/blog/archives/2011/02/"> February 2011</a> &nbsp;(1)</li><li> <a href="/blog/archives/2011/01/"> January 2011</a> &nbsp;(1)</li><li> <a href="/blog/archives/2010/10/"> October 2010</a> &nbsp;(1)</li><li> <a href="/blog/archives/2010/05/"> May 2010</a> &nbsp;(1)</li><li> <a href="/blog/archives/2010/02/"> February 2010</a> &nbsp;(1)</li>
+      <li> <a href="/blog/archives/2021/01/"> January 2021</a> &nbsp;(2)</li><li> <a href="/blog/archives/2020/09/"> September 2020</a> &nbsp;(1)</li><li> <a href="/blog/archives/2020/08/"> August 2020</a> &nbsp;(2)</li><li> <a href="/blog/archives/2020/06/"> June 2020</a> &nbsp;(2)</li><li> <a href="/blog/archives/2020/04/"> April 2020</a> &nbsp;(2)</li><li> <a href="/blog/archives/2020/03/"> March 2020</a> &nbsp;(1)</li><li> <a href="/blog/archives/2020/01/"> January 2020</a> &nbsp;(2)</li><li> <a href="/blog/archives/2019/12/"> December 2019</a> &nbsp;(1)</li><li> <a href="/blog/archives/2019/11/"> November 2019</a> &nbsp;(1)</li><li> <a href="/blog/archives/2019/08/"> August 2019</a> &nbsp;(2)</li><li> <a href="/blog/archives/2019/05/"> May 2019</a> &nbsp;(1)</li><li> <a href="/blog/archives/2018/11/"> November 2018</a> &nbsp;(1)</li><li> <a href="/blog/archives/2018/06/"> June 2018</a> &nbsp;(1)</li><li> <a href="/blog/archives/2018/03/"> March 2018</a> &nbsp;(1)</li><li> <a hr
 ef="/blog/archives/2017/12/"> December 2017</a> &nbsp;(1)</li><li> <a href="/blog/archives/2017/09/"> September 2017</a> &nbsp;(2)</li><li> <a href="/blog/archives/2017/07/"> July 2017</a> &nbsp;(1)</li><li> <a href="/blog/archives/2017/04/"> April 2017</a> &nbsp;(3)</li><li> <a href="/blog/archives/2016/12/"> December 2016</a> &nbsp;(1)</li><li> <a href="/blog/archives/2016/11/"> November 2016</a> &nbsp;(1)</li><li> <a href="/blog/archives/2016/10/"> October 2016</a> &nbsp;(1)</li><li> <a href="/blog/archives/2016/09/"> September 2016</a> &nbsp;(1)</li><li> <a href="/blog/archives/2016/07/"> July 2016</a> &nbsp;(1)</li><li> <a href="/blog/archives/2016/06/"> June 2016</a> &nbsp;(1)</li><li> <a href="/blog/archives/2016/04/"> April 2016</a> &nbsp;(2)</li><li> <a href="/blog/archives/2016/02/"> February 2016</a> &nbsp;(2)</li><li> <a href="/blog/archives/2016/01/"> January 2016</a> &nbsp;(4)</li><li> <a href="/blog/archives/2015/12/"> December 2015</a> &nbsp;(1)</li><li> <a href="/bl
 og/archives/2015/11/"> November 2015</a> &nbsp;(1)</li><li> <a href="/blog/archives/2015/10/"> October 2015</a> &nbsp;(2)</li><li> <a href="/blog/archives/2015/08/"> August 2015</a> &nbsp;(1)</li><li> <a href="/blog/archives/2015/03/"> March 2015</a> &nbsp;(1)</li><li> <a href="/blog/archives/2015/02/"> February 2015</a> &nbsp;(1)</li><li> <a href="/blog/archives/2014/12/"> December 2014</a> &nbsp;(1)</li><li> <a href="/blog/archives/2014/11/"> November 2014</a> &nbsp;(1)</li><li> <a href="/blog/archives/2014/07/"> July 2014</a> &nbsp;(2)</li><li> <a href="/blog/archives/2014/06/"> June 2014</a> &nbsp;(1)</li><li> <a href="/blog/archives/2014/05/"> May 2014</a> &nbsp;(1)</li><li> <a href="/blog/archives/2014/04/"> April 2014</a> &nbsp;(1)</li><li> <a href="/blog/archives/2014/02/"> February 2014</a> &nbsp;(8)</li><li> <a href="/blog/archives/2014/01/"> January 2014</a> &nbsp;(4)</li><li> <a href="/blog/archives/2013/12/"> December 2013</a> &nbsp;(3)</li><li> <a href="/blog/archives/
 2013/11/"> November 2013</a> &nbsp;(2)</li><li> <a href="/blog/archives/2013/09/"> September 2013</a> &nbsp;(1)</li><li> <a href="/blog/archives/2013/08/"> August 2013</a> &nbsp;(1)</li><li> <a href="/blog/archives/2013/07/"> July 2013</a> &nbsp;(1)</li><li> <a href="/blog/archives/2013/03/"> March 2013</a> &nbsp;(1)</li><li> <a href="/blog/archives/2013/02/"> February 2013</a> &nbsp;(1)</li><li> <a href="/blog/archives/2012/12/"> December 2012</a> &nbsp;(2)</li><li> <a href="/blog/archives/2012/11/"> November 2012</a> &nbsp;(2)</li><li> <a href="/blog/archives/2012/09/"> September 2012</a> &nbsp;(1)</li><li> <a href="/blog/archives/2012/08/"> August 2012</a> &nbsp;(1)</li><li> <a href="/blog/archives/2012/07/"> July 2012</a> &nbsp;(1)</li><li> <a href="/blog/archives/2012/05/"> May 2012</a> &nbsp;(2)</li><li> <a href="/blog/archives/2012/04/"> April 2012</a> &nbsp;(1)</li><li> <a href="/blog/archives/2012/02/"> February 2012</a> &nbsp;(1)</li><li> <a href="/blog/archives/2011/12/">
  December 2011</a> &nbsp;(2)</li><li> <a href="/blog/archives/2011/11/"> November 2011</a> &nbsp;(3)</li><li> <a href="/blog/archives/2011/10/"> October 2011</a> &nbsp;(1)</li><li> <a href="/blog/archives/2011/09/"> September 2011</a> &nbsp;(1)</li><li> <a href="/blog/archives/2011/07/"> July 2011</a> &nbsp;(1)</li><li> <a href="/blog/archives/2011/06/"> June 2011</a> &nbsp;(1)</li><li> <a href="/blog/archives/2011/05/"> May 2011</a> &nbsp;(1)</li><li> <a href="/blog/archives/2011/02/"> February 2011</a> &nbsp;(1)</li><li> <a href="/blog/archives/2011/01/"> January 2011</a> &nbsp;(1)</li><li> <a href="/blog/archives/2010/10/"> October 2010</a> &nbsp;(1)</li><li> <a href="/blog/archives/2010/05/"> May 2010</a> &nbsp;(1)</li><li> <a href="/blog/archives/2010/02/"> February 2010</a> &nbsp;(1)</li>
     </ul>
   </div>
 </div>



Mime
View raw message