Merge remote-tracking branch 'LCTT/master'

This commit is contained in:
Xingyu Wang 2019-11-22 17:58:59 +08:00
commit 1c2c7b4957
11 changed files with 1307 additions and 188 deletions

View File

@ -1,27 +1,26 @@
[#]: collector: (lujun9972) [#]: collector: (lujun9972)
[#]: translator: (geekpi) [#]: translator: (geekpi)
[#]: reviewer: ( ) [#]: reviewer: (wxy)
[#]: publisher: ( ) [#]: publisher: (wxy)
[#]: url: ( ) [#]: url: (https://linux.cn/article-11601-1.html)
[#]: subject: (Cleaning up with apt-get) [#]: subject: (Cleaning up with apt-get)
[#]: via: (https://www.networkworld.com/article/3453032/cleaning-up-with-apt-get.html) [#]: via: (https://www.networkworld.com/article/3453032/cleaning-up-with-apt-get.html)
[#]: author: (Sandra Henry-Stocker https://www.networkworld.com/author/Sandra-Henry_Stocker/) [#]: author: (Sandra Henry-Stocker https://www.networkworld.com/author/Sandra-Henry_Stocker/)
使用 apt-get 清理 使用 apt-get 清理
====== ======
大多数使用基于 Debian 的系统的人通常会使用 apt-get 来安装软件包和升级,但是我们多久才清理?让我们看下工具本身的一些清理选项。
[Félix Prado Modified by IDG Comm.][1] [(CC0)][2]
在基于 Debian 的系统上运行 **apt-get** 命令是很常规的。软件包的更新相当频繁,诸 如 **apt-get update****apt-get upgrade** 之类的命令使此过程非常容易。另一方面,你多久使用一次 **apt-get clean****apt-get autoclean** 或 **apt-get autoremove** > 大多数使用基于 Debian 的系统的人通常会使用 apt-get 来安装软件包和升级,但是我们多久才清理一次?让我们看下该工具本身的一些清理选项。
这些命令会在 apt-get 的安装操作后清理并删除仍在系统上但不再需要的文件,这通常是因为需要它们的程序已经卸载。 ![](https://img.linux.net.cn/data/attachment/album/201911/22/082025p39oeuufdote517e.jpg)
[[Get regularly scheduled insights by signing up for Network World newsletters.]][3] 在基于 Debian 的系统上运行 `apt-get` 命令是很常规的。软件包的更新相当频繁,诸如 `apt-get update``apt-get upgrade` 之类的命令使此过程非常容易。另一方面,你多久使用一次 `apt-get clean`、`apt-get autoclean` 或 `apt-get autoremove`
这些命令会在 `apt-get` 的安装操作后清理并删除仍在系统上但不再需要的文件,这通常是因为需要它们的程序已经卸载。
### apt-get clean ### apt-get clean
apt-get clean 命令清除遗留在 **/var/cache** 中的已检索包文件的本地仓库。它清除的目录是 **/var/cache/apt/archives/** 和 **/var/cache/apt/archives/partial/**。它留在 **/var/cache/apt/archives** 中的唯一文件是 **lock** 文件和 **partial** 子目录。 `apt-get clean` 命令清除遗留在 `/var/cache` 中的已取回的包文件的本地仓库。它清除的目录是 `/var/cache/apt/archives/``/var/cache/apt/archives/partial/`。它留在 `/var/cache/apt/archives` 中的唯一文件是 `lock` 文件和 `partial` 子目录。
在运行清理操作之前,目录中可能包含许多文件: 在运行清理操作之前,目录中可能包含许多文件:
@ -46,15 +45,15 @@ drwx------ 2 _apt root 4096 Nov 12 07:24 partial
total 0 <== 空 total 0 <== 空
``` ```
**apt-get clean** 命令通常用于根据需要清除磁盘空间,通常作为定期计划维护的一部分。 `apt-get clean` 命令通常用于根据需要清除磁盘空间,一般作为定期计划维护的一部分。
### apt-get autoclean ### apt-get autoclean
**apt-get autoclean** 类似于 **apt-get clean**,它会清除已检索包文件的本地仓库,但它只会删除不会再下载且几乎无用的文件。它有助于防止缓存过大 `apt-get autoclean` 类似于 `apt-get clean`,它会清除已检索包文件的本地仓库,但它只会删除不会再下载且几乎无用的文件。它有助于防止缓存过大
### apt-get autoremove ### apt-get autoremove
**autoremove** 选项将删除自动安装的软件包,因为某些其他软件包需要它们,但是在删除了其他软件包之后,而不再需要它们。有时会在升级时建议运行此命令。 `apt-get autoremove` 将删除自动安装的软件包,因为某些其他软件包需要它们,但是在删除了其他软件包之后,而不再需要它们。有时会在升级时建议运行此命令。
``` ```
The following packages were automatically installed and are no longer required: The following packages were automatically installed and are no longer required:
@ -66,9 +65,7 @@ The following packages were automatically installed and are no longer required:
Use 'sudo apt autoremove' to remove them. <== Use 'sudo apt autoremove' to remove them. <==
``` ```
要删除的软件包通常称为“未使用的依赖项”。实际上,一个好的做法是在卸载软件包后使用 **autoremove**,以确保不会留下不需要的文件。 要删除的软件包通常称为“未使用的依赖项”。实际上,一个好的做法是在卸载软件包后使用 `autoremove`,以确保不会留下不需要的文件。
加入 [Facebook][5] 和 [LinkedIn][6] 上的 Network World 社区,以评论最重要的话题。
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
@ -77,7 +74,7 @@ via: https://www.networkworld.com/article/3453032/cleaning-up-with-apt-get.html
作者:[Sandra Henry-Stocker][a] 作者:[Sandra Henry-Stocker][a]
选题:[lujun9972][b] 选题:[lujun9972][b]
译者:[geekpi](https://github.com/geekpi) 译者:[geekpi](https://github.com/geekpi)
校对:[校对者ID](https://github.com/校对者ID) 校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出

View File

@ -0,0 +1,135 @@
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (Zorin OS 15 Lite Release: Good Looking Lightweight Linux)
[#]: via: (https://itsfoss.com/zorin-os-lite/)
[#]: author: (Ankush Das https://itsfoss.com/author/ankush/)
Zorin OS 15 Lite Release: Good Looking Lightweight Linux
======
_**Zorin OS 15 Lite edition has just been released. Well show take you to a desktop tour of this new release and highlight its main features for you.**_
[Zorin OS][1] is an increasingly popular Linux distribution. It is based on Ubuntu and thus , unsurprisingly, it also happens to be one of the [best Linux distributions for beginners][2]. Its Windows-like interface is one of the major reasons why it is preferred by many Windows-to-Linux migrants.
Zorin OS comes in two main variants:
* Zorin Core: It uses GNOME desktop and is intended for newer systems
* Zorin Lite: It uses lightweight [Xfce desktop][3] and is intended to be the [Linux for old laptops and computers][4]
### Zorin OS 15 Lite: Whats New?
[Subscribe to our YouTube channel for more Linux videos][5]
Zorin OS 15 Lite edition has finally landed after a long time of Zorin OS 15 Core release. You can get your hands on the free lite editions or the paid ultimate lite edition now.
I tried the Zorin OS 15 Lite Ultimate edition. In this article, I shall cover the details for this release and what you should know before choosing to download Zorin OS 15 Lite for your computer.
Zorin OS 15 Lite is almost similar to the full-fledged Zorin OS 15 release. You can check out [Zorin OS 15 features][6] in our original coverage for that.
This release entirely focuses to be light on resources so that any type of old hardware configuration from the past decade can easily run on it.
![][7]
With this release, they rely on the lightweight XFCE 4.14-based desktop environment to give the best possible experience on a low-spec computer.
In addition to the XFCE desktop environment, there are some under-the-hood changes when compared to its full-fledged version that uses GNOME.
#### Zorin OS 15 Lite Targets Windows 7 Users
![][8]
Primarily, Zorin OS 15 Lite targets the Windows 7 users because the official support for Windows 7 ends this January.
So, if you are someone whos comfortable with Windows 7, you can give this a try, it should be a smooth experience switching to this.
Zorin OS 15 Lite gives you the option to switch the layout to a macOS style / Windows-style appearance from the “**Zorin Appearance**” settings.
#### 32-bit and 64-bit Support
It was good to see Zorin OS considering the support for 32-bit/64-bit ISOs just because the lite edition is being targeted for users with low-spec hardware.
#### Flatpak Support Enabled By Default
![][9]
You can utilize Flathub to install Flatpak packages out of the box using the Software Center. Make sure to check out our guide on [using Flatpak][10] if youre not sure what to do.
In addition to this, you already have the Snap package support. So, it should be easier to install anything through the Software Center.
#### User Interface Impression
![][11]
To be honest, the default Xfce interface looks old. There are ways to [customize Xfce][12] but Zorin does it out of the box. The customized look gives a good impression. It looks pretty damn neat and works as expected.
#### Performance
![][13]
Even though I havent tried this on a super old system, I did install it on a vintage hard disk drive which struggles to boot up Ubuntu or similar distributions.
As per my experience, I would definitely rate the performance to be super snappy.
It feels like I have it installed on my SSD. So, thats obviously a good thing. If you happen to try it on a super old system, you can let me know your experience in the comments section at the bottom of this article.
### Whats The Difference Between The Ultimate Lite edition &amp; Free Lite edition?
![][14]
Make no mistake, you can download Zorin OS 15 for free.
However, theres a separate Ultimate edition which is basically meant to support the developers and the project. In addition to that, it also bundles a lot of pre-installed software as an “ultimate” package for your computer.
So, if you purchase the Ultimate edition, you get access to both the lite and full version.
In case you do not want to pay for it, you can still opt for the free editions (Core, Lite, Education) depending on your requirements. You can learn more about it on their [download page][15].
### How To Download Zorin OS 15 Lite?
You can just head on to its [official download webpage][15] and scroll down to find the Zorin OS 15 lite edition.
You will find 32-bit/64-bit ISOs available, download the one you require.
[Zorin OS 15 Lite][15]
Installing Zorin OS is similar to installing Ubuntu.
**Wrapping Up**
While Zorin OS 15 is already a great offering as a Linux distribution to Windows/macOS veterans, the new Lite edition surely turns more eyes to it.
Have you tried the Lite edition yet? Let me know your thoughts in the comments below.
--------------------------------------------------------------------------------
via: https://itsfoss.com/zorin-os-lite/
作者:[Ankush Das][a]
选题:[lujun9972][b]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://itsfoss.com/author/ankush/
[b]: https://github.com/lujun9972
[1]: https://zorinos.com/
[2]: https://itsfoss.com/best-linux-beginners/
[3]: https://www.xfce.org/
[4]: https://itsfoss.com/lightweight-linux-beginners/
[5]: https://www.youtube.com/c/itsfoss?sub_confirmation=1
[6]: https://itsfoss.com/zorin-os-15-release/
[7]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/11/file-explorer-zorin-os-15-lite.jpg?ssl=1
[8]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/11/zorin-lite-ultimate-appearance.jpg?ssl=1
[9]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/11/zorin-os-software.png?ssl=1
[10]: https://itsfoss.com/flatpak-guide/
[11]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/11/zorin-os-15-lite-appearance.jpg?ssl=1
[12]: https://itsfoss.com/customize-xfce/
[13]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/11/homescreen-zorin-os-15-lite.jpg?ssl=1
[14]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/11/zorin-os-ultimate.jpg?ssl=1
[15]: https://zorinos.com/download/

View File

@ -0,0 +1,158 @@
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (What makes a programming exercise good?)
[#]: via: (https://jvns.ca/blog/2019/11/20/what-makes-a-programming-exercise-good/)
[#]: author: (Julia Evans https://jvns.ca/)
What makes a programming exercise good?
======
Ive been thinking about programming exercises lately, because I want to move into teaching people skills. But what makes a good programming exercise? I [asked about this on Twitter today][1] and got some useful responses so here are some criteria:
### its fun
This one is sort of self-explanatory and I think its really important. Programming is fun and learning is fun so I cant see why programming exercises would need to be boring.
### it teaches you something you care about
I dont think this has to strictly mean “relevant to your job right this second” people dont just have jobs, we also want to make art and games and fun personal projects and sometimes just understand the world around us. But its important to know what goals the exercise can help you with and what its related to!
Some arbitrary examples:
* take an image of something from a website and reproduce it from scratch with CSS (towards using CSS to make your own websites that look awesome)
* write a webserver from scratch without any frameworks (to learn the HTTP protocol, so that you can debug issues with a real webserver more easily)
* write a small raytracer (so you can make cool art with raytracing techniques on shaderhub!)
* write a tiny bit of assembly (as a very initial step towards understanding of what Spectre and Meltdown are even about and why we need to make all our computers run slower to prevent them)
### its a challenge
I dont know if this is everyones experience but I often start programming exercises and get bored quickly (“oh, I know how to do this, this is boring”). For me its really important for the exercise to teach me something I really dont know how to do and thats a little bit hard for me.
My favourite set of programming exercises is the [cryptopals crypto challenges][2] because they get harder pretty fast by exercise #6, youre already breaking toy encryption protocols, and by #12 youre breaking an Actual Encryption Protocol (AES in ECB mode)!
### you can tell if you succeeded
Its easy to write exercises that are too vaguely specified (“write a toy tcp stack!“). But what does that mean? How much of a TCP stack am I supposed to write? Having test cases and clear criteria for “yay! you did it! congratulations!” is really important.
### you can do it quickly
In less than 2-3 hours (an evening after work), say. Its hard to find time to spend like 8 hours on an exercise unless its REALLY exciting.
I also think that giving some specific real-world benchmark data seems nice (“I did this from scratch in 97 minutes”).
### the author believes in you
This is a bit fuzzier but very lovely [this person on Twitter wrote][3]:
> Similar to that, the writing is patient and gives me the impression that it believes in my ability to accomplish the task. … I learned a ton in the early days from Linux HOWTOs. Some gave me the sense that it was impossible to fail. Just follow the steps. Its all there.
Especially if youre doing a somewhat challenging exercise like we talked about above, I think its nice for the author to believe in your! (and of course its crucial that theyve actually written the exercises so that theyre _right_ and you can likely do the thing!)
### its been tested
I read the (great) biography [Dearie: The Remarkable Life of Julia Child][4] recently and one thing that stood out to me is that she _tested_ all of the recipes in Mastering the Art Of French Cooking. It took her _years_ to write the book and test the recipes and make sure that American home cooks actually had access to all the ingredients and had the.
I dont think all cookbook authors test their recipes, but I think testing really improves cookbooks.
I started writing some SQL exercises (like [this prototype of one on GROUP BY][5]) a while back, and at some point I realized the big thing holding me back was that I didnt have testers! I couldnt find out if people were actually learning from them or not!
This is a new thing for me because when I write blog posts I dont test them (I barely even proofread them!). I just write them and publish and people often like them and thats it! I said to [Amy Hoy][6] (who is amazing) on Twitter that I didnt understand why you have to test exercises if you dont have to test blog posts and she [pointed out][7] that people have much higher expectations for exercises than for blog posts with the blog posts you maybe expect to learn 1-2 new facts, but with exercises you expect to actually develop a new skill!
Also, people are often investing a lot more time in exercises (especially if they have to set up a dev environment or something!), so its extra important to make sure that they actually work.
### you wont get stuck
Its SO EASY to get stuck on some random irrelevant point in a programming exercise thats totally unrelated to the skill youre trying to learn. For example there might be an easily-avoidable mistake that you can make with the exercise and spend a lot of time debugging but it doesnt actually teach you a lot.
### its easy to get help
If youre doing a challenging exercise, you might want to get help from your friends / colleagues / the internet!
Some things that can go wrong:
* None of your friends have ever heard of the thing the exercise is teaching so you cant talk about it with them
* The exercise expects you to be using the newest version of some software, but actually all the examples on the internet are for some older version so its difficult to search for help even though the exercise is technically correct
* The community around the tech used in the exercise is hostile/unhelpful
One obvious way to accomplish this is by letting people use the programming language theyre most comfortable in, because they probably already know how to Google for help in that environment.
### no time-consuming setup required
Installing software is boring, and a lot of programming projects require installing software! A few things that can go wrong with this (though there are a lot more than this!)
* I get a compiler error when I try to install this package on my computer
* The example actually requires some very specific package versions to work properly and if you dont have those exact versions installed you get a bunch of cryptic errors and need to google for 3 hours to fix them
This kind of thing is a huge waste of time and super demoralizing. And its not trivial to avoid! If youre trying to teach someone a specific piece of software, often that software
A few options Ive seen or used to manage this:
* tell people what you know works (“Ive tested this in Mac/Linux but not Windows”)
* avoid requiring any software to be installed (“just use python”)
* use Docker to run everything
* run all the code in the persons browser (because browsers usually do about the same thing)
* use a cloud system (so everything runs on someone elses computer). This is what I do for my [pandas cookbook][8], which lets you run it in Binder, this really great free service for hosting Jupyter notebooks.
### its easy to extend
@tef has this great talk on Scratch [A million things to do with a computer!][9] which explains the 3 ideas of Scratch:
* low floors
* wide walls
* high ceilings
It sucks when you start learning something and then learn that what you can do with the Thing is very limited! Its exciting when you learn something and see “oh, wow, there are SO MANY POSSIBILITIES, what if I did X instead?”
### thats a lot of things!
The criteria we arrived at:
* fun exercises
* that teach you something you care about
* that are challenging
* with clear success criteria
* that can be done quickly
* with no complicated setup
* and few hidden gotchas
* using a tech stack thats easy for you to get help with
* where theres a lot of room to grow
That seems pretty hard, but it seems like a good goal to aspire to! Im going to keep very slowly working on exercises!
--------------------------------------------------------------------------------
via: https://jvns.ca/blog/2019/11/20/what-makes-a-programming-exercise-good/
作者:[Julia Evans][a]
选题:[lujun9972][b]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://jvns.ca/
[b]: https://github.com/lujun9972
[1]: https://twitter.com/b0rk/status/1197282185230860288
[2]: https://cryptopals.com/
[3]: https://twitter.com/mojavelinux/status/1197323090427953152
[4]: https://www.amazon.com/exec/obidos/ASIN/0307473414/metafilter-20/ref=nosim/
[5]: https://joins-238123.netlify.com/aggregations/
[6]: https://stackingthebricks.com/
[7]: https://twitter.com/amyhoy/status/1197291805449940993
[8]: https://github.com/jvns/pandas-cookbook
[9]: https://www.youtube.com/watch?v=vU9myNJI9l4

View File

@ -0,0 +1,64 @@
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (Cumulus Networks updates its network-centric Linux distribution)
[#]: via: (https://www.networkworld.com/article/3454338/cumulus-networks-updates-its-network-centric-linux-distribution.html)
[#]: author: (Andy Patrizio https://www.networkworld.com/author/Andy-Patrizio/)
Cumulus Networks updates its network-centric Linux distribution
======
Company says its Linux is to networking what Red Hat is to servers.
Thinkstock
The [Linux][1] distribution ecosystem is pretty set, with Red Hat and Canonical in the leadership positions, followed closely by SuSe and home brews from the likes of IBM and other major vendors. Even Microsoft has its own distro for Azure users.
And then there is Cumulus Networks, which specializes in networking software. It just released Cumulus Linux 4.0 and NetQ 2.4, its cloud network deployment and management console. With this release, Cumulus is claiming its Linux is its most stable and reliable software stack yet and NetQ is the most comprehensive end-to-end network automation product.
[[Get regularly scheduled insights by signing up for Network World newsletters.]][2]
Roopa Prabhu, chief Linux architect at Cumulus, said that just as Red Hat Enterprise Linux is designed for servers, Cumulus Linux is specifically designed for networking.
**[ [Become a Microsoft Office 365 administrator in record time with this quick start course from PluralSight.][3] ]**
"Unlike RHEL, Ubuntu or Suse, Cumulus Linux is specially designed for the unique needs of a network device, like a [data-center][4] switch," he said in an email to me. "Cumulus Linux comes packaged with drivers for data-center switch hardware, the latest and greatest in Linux-kernel networking, a rich networking protocol stack with Free Range Routing (FRR), multi-homing protocol software, networking tools and Linux defaults optimized for networking.”
“RHEL for example, complements Cumulus Linux in the data center, rather than compete with it, allowing similar management and orchestration tools across compute and network devices," he added.
By being native Linux, Cumulus says it provides support for all the tooling and applications of the Linux ecosystem while providing advanced networking features and support, including kernel additions for VRF, VxLAN or the upstreamed ifupdown2 network-interface manager. 
Cumulus Linux 4.0 includes:
* Support for 134 hardware platforms across 14 ASICs.
* Support for Mellanoxs Spectrum-2 chipset for faster performance, Broadcoms Qumran chipset for deep buffering at the top of rack, Facebooks Minipack an open, modular chassis with a single 12.8TB chip, and additional campus networking platforms with Dell.
* Migration to the latest and most advanced Linux kernel for greater route scale, the latest security updates, and thousands of contributions from the broader Linux community.
* Support for SwitchDev, an open source in-kernel abstraction model, providing a standardized way to program switch ASICs and speed development time.
* Enhancements to its EVPN implementation (EVPN-PIM and EVPN multi-homing) for Layer 2/Layer3 connectivity.
* Comprehensive end-to-end automation for CI/CD workflows including simulation, validation, troubleshooting and NetDevOps practices such as Infrastructure-as-Code (IaC).
* The ability to build a single fabric across data center and campus environments enabling a common operational model.
*  
Join the Network World communities on [Facebook][5] and [LinkedIn][6] to comment on topics that are top of mind.
--------------------------------------------------------------------------------
via: https://www.networkworld.com/article/3454338/cumulus-networks-updates-its-network-centric-linux-distribution.html
作者:[Andy Patrizio][a]
选题:[lujun9972][b]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://www.networkworld.com/author/Andy-Patrizio/
[b]: https://github.com/lujun9972
[1]: https://www.networkworld.com/article/3215226/what-is-linux-uses-featres-products-operating-systems.html
[2]: https://www.networkworld.com/newsletters/signup.html
[3]: https://pluralsight.pxf.io/c/321564/424552/7490?u=https%3A%2F%2Fwww.pluralsight.com%2Fcourses%2Fadministering-office-365-quick-start
[4]: https://www.networkworld.com/article/3223692/what-is-a-data-centerhow-its-changed-and-what-you-need-to-know.html
[5]: https://www.facebook.com/NetworkWorld/
[6]: https://www.linkedin.com/company/network-world

View File

@ -0,0 +1,71 @@
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (IoT sensors must have two radios for efficiency)
[#]: via: (https://www.networkworld.com/article/3454404/iot-sensors-must-have-two-radios-for-efficiency.html)
[#]: author: (Patrick Nelson https://www.networkworld.com/author/Patrick-Nelson/)
IoT sensors must have two radios for efficiency
======
To extend battery life, IoT radios that send data should be powered only when there's data to send, and a second, power-sipper radio should just listen for a wake-up signal for the principal radio. Academics say theyre making progress getting that all to work.
Jorgen Norgaard / WhatAWin / Getty Images
For the [Internet of Things][1] to become ubiquitous, many believe that inefficiencies in the powering of sensors and radios has got to be eliminated. Battery chemistry just isnt good enough, and its simply too expensive to continually perform truck-rolls, for example, whenever batteries need changing out. In many cases, solar battery-top-ups arent the solution because that, usually-fixed, technology isnt particularly suited to mobile, or impromptu, ad hoc networks.
Consequently, theres a dash going on to try to find either better chemistries that allow longer battery life or more efficient chips and electronics that just sip electricity. An angle of thought being followed is to wake-up network radios only when they need to transmit a burst of data. Universities say they are making significant progress in this area.
[[Get regularly scheduled insights by signing up for Network World newsletters.]][2]
“The problem now is that these [existing] devices do not know exactly when to synchronize with the network, so they periodically wake up to do this even when theres nothing to communicate,” explains Patrick Mercier, a professor of electrical and computer engineering at the University of California, San Diego, in a [media release][3]. “By adding a wake-up receiver, we could improve the battery life of small IoT devices from months to years,” he says.
[][4]
BrandPost Sponsored by HPE
[Take the Intelligent Route with Consumption-Based Storage][4]
Combine the agility and economics of HPE storage with HPE GreenLake and run your IT department with efficiency.
### Wake-up
The school says that the key to getting the wake-up receivers to be useful is to implement them at very high frequencies. The reason: everything gets smaller, including antennas the higher in spectrum one goes. It “allowed researchers to shrink everything, including the antenna, transformer and other off-chip components down into a much smaller package,” the school explains. The schools solution is at 9 GHz, in X Band.
The device functions using specific radio signals, called a wake-up signature, being directed at an IoT sensors dedicated wake-up receiver chip. That radio can operate with less energy consumption than the data radio chip because its only purpose is to listen for the wake-up signature. UC San Diegos device uses only 22.3 nanowatts. Thats around half-a-millionth of the power that an LED night light uses, the school claims. Another, more energy-consuming radio, then, which is switched on as necessary by the wake-up radio, performs the more heavy-duty tasks like actually sending the data.
Stanford University has also been working on IoT wake-up solutions. [I wrote about its one nanowatt, ultrasound device in 2018][5]. Thats dog-whistle-like frequency. That school, too, is working on the premise that using higher frequencies means one can design smaller electronics packages. The university claimed then on its website that its chip used “about a billionth the power it takes to light a single old-fashioned Christmas bulb.”
Importantly, both universities solutions allow the actual power-hog data radio to be off while not in use, not just dormant or sleeping as is common now.
### High sensitivity
UC San Diego believes its X Band device has advantages over anything that has come before on two additional counts. It explains that its design performs well in varied ambient temperatures: It claims usability from 14 F to 104 F. That temperature range means wake-up could be used in implementations outside, such as in the maritime vertical, for example.
The university also says its sensitivity numbers are the best that have ever been [published in a study][6] at -69.5 dBm. Latency is a trade-off, though, as theres a 540ms delay. But thats likely not a problem for much IoT use, like short burst, periodic data sends, such as are used for environmental sensing, for example.
“These numbers are pretty impressive in the field of wireless communications. Power consumption that low, while still retaining temperature robustness, all in a small, highly sensitive system,” Mercier says. "This will enable all sorts of new IoT applications.”
Join the Network World communities on [Facebook][7] and [LinkedIn][8] to comment on topics that are top of mind.
--------------------------------------------------------------------------------
via: https://www.networkworld.com/article/3454404/iot-sensors-must-have-two-radios-for-efficiency.html
作者:[Patrick Nelson][a]
选题:[lujun9972][b]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://www.networkworld.com/author/Patrick-Nelson/
[b]: https://github.com/lujun9972
[1]: https://www.networkworld.com/article/3207535/what-is-iot-how-the-internet-of-things-works.html
[2]: https://www.networkworld.com/newsletters/signup.html
[3]: https://ucsdnews.ucsd.edu/pressrelease/new-chip-for-waking-up-small-wireless-devices-could-extend-battery-life
[4]: https://www.networkworld.com/article/3440100/take-the-intelligent-route-with-consumption-based-storage.html?utm_source=IDG&utm_medium=promotions&utm_campaign=HPE20773&utm_content=sidebar ( Take the Intelligent Route with Consumption-Based Storage)
[5]: https://www.networkworld.com/article/3254200/small-wake-up-receivers-could-extend-iot-sensor-life.html
[6]: https://ieeexplore.ieee.org/document/8890666
[7]: https://www.facebook.com/NetworkWorld/
[8]: https://www.linkedin.com/company/network-world

View File

@ -0,0 +1,115 @@
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (Three-course professional specialization aims to close the gap between the use and understanding of open source in business)
[#]: via: (https://opensource.com/article/19/11/open-source-management-course)
[#]: author: (Don Watkins https://opensource.com/users/don-watkins)
Three-course professional specialization aims to close the gap between the use and understanding of open source in business
======
Quickly climb the learning curve of open source with lessons distilled
from experienced practitioners.
![Coding on a computer][1]
Even though open source software (OSS) is pervasive in IT, many people in business don't understand what open source is and how it differs from proprietary software. [According to Brandeis University][2], "open source software now accounts for between 78% and 98% of all core digital infrastructure, yet few organizational managers understand the business behind it."
In an effort to close the gap between open source usage and understanding, Brandeis and the [Open Source Initiative][3] (OSI) have launched a three-course specialization in [Open Source Technology Management][4]. After attending an information session about the new program at [All Things Open 2019][5], I was eager to learn more about it and how it will be delivered and assessed, so I reached out to the leadership at Brandeis and the OSI over email for more information. (The interview has been slightly edited for length and clarity.)
**Don Watkins:** **How will the course prepare students to successfully deploy open source software and effectively engage in open source production?**
[**Patrick Masson**][6]**,** **OSI general manager and board director:** The OSI receives many questions from all sorts of organizations—companies, governments, non-profits—and individuals who are just beginning to explore open source software. Many of these inquiries share a few common themes around acquisition, implementation, support, and development, such as: How do we "buy" open source software, and where do we send the RFP? Do we need to hire a programmer if we use open source software? Will the open source project provide end-user or technical support?
The OSI hopes the courses can prepare students by introducing the business case for open source, including business models, the value proposition, organizational practices, and operational and community processes. There are actually three courses: [The Business of Open Source][2], [Open Source Community Development][7], and [Open Source Development Fundamentals][8].
**DW:** **How will students be challenged to assess traditional organizational practices and measure their capacity to manage reform in light of the differences presented by open source? Can you teach open source? How do you assess community building? Can it be assessed?**
[**James Vasile**][9]**, Open Source Technology Management faculty:** I don't want to frame these classes as presenting an approach in opposition to traditional development models. Free and open source software (FOSS) is its own way of fostering technical collaboration. To think of it as "reform" or to define it in terms of other models is to miss the point. Open source strategies are useful, and they often appear right alongside other approaches.
Open source is a range of practices, a set of licenses, a diverse community, a strategic approach, and even an ethos. There's no one thing to teach. Rather, it's a whole field. Engaging that field can be useful if you know what you're doing. Right now, the primary way people learn the field is by spending a decade contributing to open source efforts. We are distilling the lessons learned by many experienced practitioners and trying to help people climb the learning curve quicker.
Metrics are, of course, a huge topic in the FOSS world right now. There's no one-size-fits-all way to measure or assess community health and growth. What we do have is a set of context-specific indicators that can fit narratives. These indicators tell you where to dig. You don't know whether you've struck truth or not until you get below the surface.
**PM:** I'll echo James' comments. From an OSI perspective, we see successful open source projects using a variety of tools and techniques for governance and decision-making, communication and collaboration, community development, project management, design and development, etc. There is no single path to open source, so rather than telling students "how" to do open source, I am hoping we can help students understand "what" makes open source. I think it's about behavior and principles vs. step-by-step processes.
That's not to say that working with open source software and communities won't introduce change into how organizations operate. Many examples exist. If an organization has formal procurement processes, it may need to reassess how to include open source options that may not be able to participate in typical RFI/RFPs. If an organization is accustomed to driving development around their technologies, they will need to adjust their practices to work with communities.
One of the really exciting things the courses can provide is real-world case studies that exemplify how organizations—companies, governments, etc.—are successfully engaging with, contributing to, and developing open source software. Each of these companies, I expect, will have discovered unique approaches, but I suspect there will be common themes. The students will learn to identify and understand those so they can take them back to their own organizations.
**DW:** **What best practice models will be used?**
**PM:** Each faculty member will employ teaching methods they are most comfortable with. Brandeis also has a fantastic instructional design group that can help faculty develop the courses, create learning resources, and design activities.
As to the course content, the courses will introduce successful open source projects, as well as provide case studies showing companies that are successful in their adoption of open source. Students will look at what the companies are doing to create community, raise awareness and adoption, manage development, and all the other things vital to open source communities of practice. Then students are tasked to find common themes, shared practices, and even unique traits. These will inform their own work as they move into open source careers.
[**Carol Damm**][10]**,** **director of programs and assessment for graduate professional studies at Brandeis:** As Patrick explained, students will review examples or case studies of OSS adoption. This is an established teaching approach that enables students to apply the concepts that they are learning to real-world situations.
**DW:** **How will students learn about the community? Will there be opportunities for them to join open source communities as members? How?**
**PM:** We have a dedicated course, "[Open Source Community Development][7]," that is designed to help students understand the various roles in communities of practice supporting open source software development, adoption, and maintenance.
This course presents a great opportunity to have students involved in open source communities as part of the course. The students may not be contributing directly to the projects, but they can do field observations. Getting students to engage with projects to discover how they share information, foster communication, manage financials, make decisions, and all the other critical practices that open source communities need to be successful.
I'll also offer that the courses can incorporate any open source projects students' companies may be working with—especially if internal contributions are being made upstream. This would provide a powerful opportunity to assess the issues the students' companies are going through, how they resolved them, and what remains.
**DW: The production of open, distributed, and community-driven software requires design and development methodologies and workflows that support the advantages of peer-to-peer, highly collaborative, iterative production. How will that be facilitated?**
**CD**: The intent is to create activities and assignments around the workflow and processes that are part of the OSS organizational practices. These activities and assignments will require students to collaborate, creating a relational experience, common to the OSS community.
**[Ken Udas][11], Open Source Initiative program chair at Brandeis**: Learning is an iterative process and will be facilitated in these courses through exposure to the practice of experienced faculty members and guest lecturers to guide hands-on practice. Although the activities will be determined and developed by the teaching staff, we all want the students to leave with the benefit of practicing under the guidance of knowledgeable practitioners and teachers.
So, in a particular class, the production process might be introduced through a semester-long case study, perhaps based on an active OSS community or a situation in which there is an internal development or perhaps an effort within an organization to adopt an open source technology and contribute to a community. We are committed to having the teacher and course designer build learning experiences that expose students to practice such that learning can be meaningfully facilitated and iteratively applied. This process will be unique for each teacher. In short, the learner will participate in learning experiences that are facilitated by the instructor with OSS experience, based on practice.
Iterative and peer-based production in the courses is promoted through exposure through faculty modeling and observation of active OSS communities in practice. Iterative methodologies will be embedded in weekly forum activities and assignments in each course. In addition, it is important to remember that the course itself is subject to interactive development and improvement. Students will also be expected to contribute, using iterative design principles, to the ongoing development of the course along with the teacher and staff.
**DW:** **What metrics will be used to assess the effectiveness of instruction? How will credit be assigned? What will assessments look like?**
**CD:** The students will work collaboratively on assignments that present cases either that are given to them or of their choosing, depending on the course, in which they apply the practice that they are learning about. Problem-based learning is a student-centered approach that creates a space for critical thinking and collaborative work. These assignments are graded and aligned to the course outcomes to evaluate students' achievement.
**KU:** Instructional effectiveness is a matter of student assessment and self-assessment, which is also reflected in the success of learners, as illustrated through the products created during the class. Although the assessments will vary from class-to-class and teacher-to-teacher, they will take the form of artifacts and evidence of methodology in practice. Credit within the class will be in large part determined by the course developer and learning designer but will generally be a balance between group and individual assignment.
**DW:** **What** **are** **the** **outcomes for students? An MBA focus? Digital badges?**
**CD: **With the completion of the three courses, students will receive a digital credential in the form of a badge that will carry the details of the credential in its metadata.
**DW:** **What's in it for the Open Source Initiative? What are the takeaways for the OSI?**
**PM:** These courses fit squarely into the OSI's mission to "educate about and advocate for the benefits of open source and to build bridges among different constituencies in the open source community." We currently have several other educational initiatives, for example, in K-12 ([FLOSS Desktops for Kids][12]) and for government ([Open Source and Standards Working Group][13]).
While the OSI has always been active in education and advocacy, our interest in formal educational opportunities was sparked after reading the [Open Source Program Management 2018 Survey][14]. Its key findings highlighted a growing demand for professionals, not necessarily from technical backgrounds, who may be supporting open source within a company: HR staff hiring for roles that support external projects, procurement officers and contract managers who need to engage open source communities, project and product managers who need to work with external organizations, budgeting staff who need to assess ROI on open source implementations. Where are students from MBA or marketing and communications programs, who are interested in working with technology, learning about open source software?
There are a small but growing number of individual faculty and departments within colleges and universities that include open source software development in their curriculum—usually for technical programs (e.g., CompSci, EE)—however, open source specializations for non-technical disciplines are rare. I only know of [one][15]. The Brandeis specialization allows us to introduce open source into traditional academic programs.
The Brandeis specialization also allows us to introduce open source to non-traditional learners. The OSI also needs to help the self-directed, self-motivated learners who may have discovered open source software and development through their own personal educational experiences. One of the great opportunities, rightly, touted by open source advocates is access to "learning by doing" made possible through open source communities. Open source projects can reduce barriers to access, allowing non-traditional students to learn to program, discover the latest technologies, gain new skills, even network to build professional relationships. Again, these opportunities are not limited to those seeking technical skills. Open source projects rely on those with business, finance, marketing, communications, and many other skills. Brandeis will also be offering the three courses as a digital badge for individuals who may not be interested in a degree program.
The OSI recognizes that open source now spans all industries and impacts every department within the organization, from simple end users to maintainers of internally developed projects. The OSI wants to help both those seeking careers in open source and the industries that need those professionals. As a trusted source and recognized authority within the open source community, we feel we can provide guidance on the design and development of courses and content and lend credibility to assure both students and employers that the program will provide a quality, relevant, educational experience.
--------------------------------------------------------------------------------
via: https://opensource.com/article/19/11/open-source-management-course
作者:[Don Watkins][a]
选题:[lujun9972][b]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/don-watkins
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/code_computer_laptop_hack_work.png?itok=aSpcWkcl (Coding on a computer)
[2]: https://www.brandeis.edu/gps/future-students/learn-about-our-programs/open-source-technology-management.html#business
[3]: https://opensource.org/
[4]: https://www.brandeis.edu/gps/future-students/learn-about-our-programs/open-source-technology-management.html#
[5]: https://allthingsopen.org/
[6]: https://www.linkedin.com/in/patrick-masson-4a09b53/
[7]: https://www.brandeis.edu/gps/future-students/learn-about-our-programs/open-source-technology-management.html#community
[8]: https://www.brandeis.edu/gps/future-students/learn-about-our-programs/open-source-technology-management.html#development
[9]: https://www.linkedin.com/in/jamesvasile/
[10]: https://www.linkedin.com/in/carol-damm-id/
[11]: https://www.brandeis.edu/facultyguide/person.html?emplid=9ea81c0b94ebc262f10d2065827733c2e903cafd
[12]: https://opensource.com/article/17/9/floss-desktops-kids
[13]: https://wiki.opensource.org/bin/Working+Groups+%26+Incubator+Projects/OSandStandardsWG/
[14]: https://todogroup.org/blog/survey-2018/
[15]: https://www.rit.edu/study/free-and-open-source-software-and-free-culture-minor

View File

@ -1,170 +0,0 @@
[#]: collector: (lujun9972)
[#]: translator: (geekpi)
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (How containers work: overlayfs)
[#]: via: (https://jvns.ca/blog/2019/11/18/how-containers-work--overlayfs/)
[#]: author: (Julia Evans https://jvns.ca/)
How containers work: overlayfs
======
I wrote a comic about overlay filesystems for a potential future container [zine][1] this morning, and then I got excited about the topic and wanted to write a blog post with more details. Heres the comic, to start out:
<https://jvns.ca/images/overlay.jpeg>
### container images are big
Container images can be pretty big (though some are really small, like [alpine linux is 2.5MB][2]). Ubuntu 16.04 is about 27MB, and [the Anaconda Python distribution is 800MB to 1.5GB][3].
Every container you start with an image starts out with the same blank slate, as if it made a copy of the image just for that container to use. But for big container images, like that 800MB Anaconda image, making a copy would be both a waste of disk space and pretty slow. So Docker doesnt make copies instead it uses an **overlay**.
### how overlays work
Overlay filesystems, also known as “union filesystems” or “union mounts” let you mount a filesystem using 2 directories: a “lower” directory, and an “upper” directory.
Basically:
* the **lower** directory of the filesystem is read-only
* the **upper** directory of the filesystem can be both read to and written from
When a process **reads** a file, the overlayfs filesystem driver looks in the upper directory and reads the file from there if its present. Otherwise, it looks in the lower directory.
When a process **writes** a file, overlayfs will just write it to the upper directory.
### lets make an overlay with `mount`!
That was all a little abstract, so lets make an overlay filesystem and try it out! This is just going to have a few files in it: Ill make upper and lower directories, and a `merged` directory to mount the combined filesystem into:
```
$ mkdir upper lower merged work
$ echo "I'm from lower!" > lower/in_lower.txt
$ echo "I'm from upper!" > upper/in_upper.txt
$ # `in_both` is in both directories
$ echo "I'm from lower!" > lower/in_both.txt
$ echo "I'm from upper!" > upper/in_both.txt
```
Combining the upper and lower directories is pretty easy: we can just do it with `mount!`
```
$ sudo mount -t overlay overlay
-o lowerdir=/home/bork/test/lower,upperdir=/home/bork/test/upper,workdir=/home/bork/test/work
/home/bork/test/merged
```
Theres was an extremely annoying error message I kept getting while doing this, that said `mount: /home/bork/test/merged: special device overlay does not exist.`. This message is a lie, and actually just means that one of the directories I specified was missing (Id written `~/test/merged` but it wasnt being expanded).
Okay, lets try to read one of the files from the overlay filesystem! The file `in_both.txt` exists in both `lower/` and `upper/`, so it should read the file from the `upper/` directory.
```
$ cat merged/in_both.txt
"I'm from upper!
```
It worked!
And the contents of our directories are what wed expect:
```
find lower/ upper/ merged/
lower/
lower/in_lower.txt
lower/in_both.txt
upper/
upper/in_upper.txt
upper/in_both.txt
merged/
merged/in_lower.txt
merged/in_both.txt
merged/in_upper.txt
```
### what happens when you create a new file?
```
$ echo 'new file' > merged/new_file
$ ls -l */new_file
-rw-r--r-- 1 bork bork 9 Nov 18 14:24 merged/new_file
-rw-r--r-- 1 bork bork 9 Nov 18 14:24 upper/new_file
```
That makes sense, the new file gets created in the `upper` directory.
### what happens when you delete a file?
Reads and writes seem pretty straightforward. But what happens with deletes? Lets do it!
```
$ rm merged/in_both.txt
```
What happened? Lets look with `ls`:
```
ls -l upper/in_both.txt lower/lower1.txt merged/lower1.txt
ls: cannot access 'merged/in_both.txt': No such file or directory
-rw-r--r-- 1 bork bork 6 Nov 18 14:09 lower/in_both.txt
c--------- 1 root root 0, 0 Nov 18 14:19 upper/in_both.txt
```
So:
* `in_both.txt` is still in the `lower` directory, and its unchanged
* its not in the `merged` directory. So far this is all what we expected.
* But what happened in `upper` is a little strange: theres a file called `upper/in_both.txt`, but its a… character device? I guess this is how the overlayfs driver represents a file being deleted.
What happens if we try to copy this weird character device file?
```
$ sudo cp upper/in_both.txt upper/in_lower.txt
cp: cannot open 'upper/in_both.txt' for reading: No such device or address
```
Okay, that seems reasonable, being able to copy this weird deletion signal file doesnt really make sense.
### you can mount multiple “lower” directories
Docker images are often composed of like 25 “layers”. Overlayfs supports having multiple lower directories, so you can run
```
mount -t overlay overlay
-o lowerdir:/dir1:/dir2:/dir3:...:/dir25,upperdir=...
```
So I assume thats how containers with many Docker layers work, it just unpacks each layer into a separate directory and then asks overlayfs to combine them all together together with an empty upper directory that the container will write its changes to it.
### docker can also use btrfs snapshots
Right now Im using ext4, and Docker uses overlayfs snapshots to run containers. But I used to use btrfs, and then Docker would use btrfs copy-on-write snapshots instead. (Heres a list of when Docker uses which [storage drivers][4])
Using btrfs snapshots this way had some interesting consequences at some point last year I was running hundreds of short-lived Docker containers on my laptop, and this resulted in me running out of btrfs metadata space (like [this person][5]). This was really confusing because Id never heard of btrfs metadata before and it was tricky to figure out how to clean up my filesystem so I could run Docker containers again. ([this docker github issue][6] describes a similar problem with Docker and btrfs)
### its fun to try out container features in a simple way!
I think containers often seem like theyre doing “complicated” things and I think its fun to break them down like this you can just run one `mount` incantation without actually doing anything else related to containers at all and see how overlays work!
--------------------------------------------------------------------------------
via: https://jvns.ca/blog/2019/11/18/how-containers-work--overlayfs/
作者:[Julia Evans][a]
选题:[lujun9972][b]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://jvns.ca/
[b]: https://github.com/lujun9972
[1]: https://wizardzines.com
[2]: https://hub.docker.com/_/alpine?tab=tags
[3]: https://hub.docker.com/r/continuumio/anaconda3/tags
[4]: https://docs.docker.com/storage/storagedriver/select-storage-driver/
[5]: https://www.reddit.com/r/archlinux/comments/5jrmfe/btrfs_metadata_and_docker/
[6]: https://github.com/moby/moby/issues/27653

View File

@ -1,5 +1,5 @@
[#]: collector: (lujun9972) [#]: collector: (lujun9972)
[#]: translator: ( ) [#]: translator: (geekpi)
[#]: reviewer: ( ) [#]: reviewer: ( )
[#]: publisher: ( ) [#]: publisher: ( )
[#]: url: ( ) [#]: url: ( )

View File

@ -0,0 +1,180 @@
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (How to document Python code with Sphinx)
[#]: via: (https://opensource.com/article/19/11/document-python-sphinx)
[#]: author: (Moshe Zadka https://opensource.com/users/moshez)
How to document Python code with Sphinx
======
Documentation is best as part of the development process. Sphinx, along
with Tox, makes it easy to write and beautiful to look at.
![Python in a coffee cup.][1]
Python code can include documentation right inside its source code. The default way of doing so relies on **docstrings**, which are defined in a triple quote format. While the value of documentation is well... documented, it seems all too common to not document code sufficiently. Let's walk through a scenario on the power of great documentation.
After one too many whiteboard tech interviews that ask you to implement the Fibonacci sequence, you have had enough. You go home and write a reusable Fibonacci calculator in Python that uses floating-point tricks to get to O(1).
The code is pretty simple:
```
# fib.py
import math
_SQRT_5 = math.sqrt(5)
_PHI = (1 + _SQRT_5) / 2
def approx_fib(n):
    return round(_PHI**(n+1) / _SQRT_5)
```
(That the Fibonacci sequence is a geometric sequence rounded to the nearest whole number is one of my favorite little-known math facts.)
Being a decent person, you make the code open source and put it on [PyPI][2]. The **setup.py** file is simple enough:
```
import setuptools
setuptools.setup(
    name='fib',
    version='2019.1.0',
    description='Fibonacci',
    py_modules=["fib"],
)
```
However, code without documentation is useless. So you add a docstring to the function. One of my favorite docstring styles is the ["Google" style][3]. It is light on markup, which is nice when it is inside the source code.
```
def approx_fib(n):
    """
    Approximate Fibonacci sequence
    Args:
        n (int): The place in Fibonacci sequence to approximate
    Returns:
        float: The approximate value in Fibonacci sequence
    """
    # ...
```
But the function's documentation is only half the battle. Prose documentation is important for contextualizing code usage. In this case, the context is annoying tech interviews. 
There is an option to add more documentation, and the Pythonic pattern is to use an **rst** file (short for [reStructuredText][4]) commonly added under a **docs/** directory. So the **docs/index.rst** file ends up looking like this:
```
Fibonacci
=========
Are you annoyed at tech interviewers asking you to implement
the Fibonacci sequence?
Do you want to have some fun with them?
A simple
:code:`pip install fib`
is all it takes to tell them to,
um,
fib off.
.. automodule:: fib
   :members:
```
And we're done, right? We have the text in a file. Someone should look at it.
### Making Python documentation beautiful
To make your documentation look beautiful, you can take advantage of [Sphinx][5], which is designed to make pretty Python documents. In particular, these three Sphinx extensions are helpful:
* **sphinx.ext.autodoc**: Grabs documentation from inside modules
* **sphinx.ext.napoleon**: Supports Google-style docstrings
* **sphinx.ext.viewcode**: Packages the ReStructured Text sources with the generated docs
In order to tell Sphinx what and how to generate, we configure a helper file at **docs/conf.py**:
```
extensions = [
    'sphinx.ext.autodoc',
    'sphinx.ext.napoleon',
    'sphinx.ext.viewcode',
]
# The name of the entry point, without the ".rst" extension.
# By convention this will be "index"
master_doc = "index"
# This values are all used in the generated documentation.
# Usually, the release and version are the same,
# but sometimes we want to have the release have an "rc" tag.
project = "Fib"
copyright = "2019, Moshe Zadka"
author = "Moshe Zadka"
version = release = "2019.1.0"
```
This file allows us to release our code with all the metadata we want and note our extensions (the comments above explain how). Finally, to document exactly how we want the documentation generated, use [Tox][6] to manage the virtual environment to make sure we generate the documentation smoothly:
```
[tox]
# By default, .tox is the directory.
# Putting it in a non-dot file allows opening the generated
# documentation from file managers or browser open dialogs
# that will sometimes hide dot files.
toxworkdir = {toxinidir}/build/tox
[testenv:docs]
# Running sphinx from inside the "docs" directory
# ensures it will not pick up any stray files that might
# get into a virtual environment under the top-level directory
# or other artifacts under build/
changedir = docs
# The only dependency is sphinx
# If we were using extensions packaged separately,
# we would specify them here.
# A better practice is to specify a specific version of sphinx.
deps =
    sphinx
# This is the sphinx command to generate HTML.
# In other circumstances, we might want to generate a PDF or an ebook
commands =
    sphinx-build -W -b html -d {envtmpdir}/doctrees . {envtmpdir}/html
# We use Python 3.7. Tox sometimes tries to autodetect it based on the name of
# the testenv, but "docs" does not give useful clues so we have to be explicit.
basepython = python3.7
```
Now, whenever you run Tox, it will generate beautiful documentation for your Python code.
### Documentation in Python is excellent
As a Python developer, the toolchain available to us is fantastic. We can start with **docstrings**, add **.rst** files, then add Sphinx and Tox to beautify the results for users. 
What do you appreciate about good documentation? Do you have other favorite tactics? Share them in the comments!
--------------------------------------------------------------------------------
via: https://opensource.com/article/19/11/document-python-sphinx
作者:[Moshe Zadka][a]
选题:[lujun9972][b]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/moshez
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/coffee_python.jpg?itok=G04cSvp_ (Python in a coffee cup.)
[2]: https://pypi.org/
[3]: http://google.github.io/styleguide/pyguide.html#381-docstrings
[4]: http://docutils.sourceforge.net/rst.html
[5]: http://www.sphinx-doc.org/en/master/
[6]: https://tox.readthedocs.io/en/latest/

View File

@ -0,0 +1,399 @@
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (Simulate gravity in your Python game)
[#]: via: (https://opensource.com/article/19/11/simulate-gravity-python)
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
Simulate gravity in your Python game
======
Learn how to program video games with Python's Pygame module and start
manipulating gravity.
![Cosmic stars in outer space][1]
The real world is full of movement and life. The thing that makes the real world so busy and dynamic is physics. Physics is the way matter moves through space. Since a video game world has no matter, it also has no physics, so game programmers have to _simulate_ physics.
In terms of most video games, there are basically only two aspects of physics that are important: gravity and collision.
You implemented some collision detection when you [added an enemy][2] to your game, but this article adds more because gravity requires collision detection. Think about why gravity might involve collisions. If you can't think of any reasons, don't worry—it'll become apparent as you work through the sample code.
Gravity in the real world is the tendency for objects with mass to be drawn toward one another. The larger the object, the more gravitational influence it exerts. In video game physics, you don't have to create objects with mass great enough to justify a gravitational pull; you can just program a tendency for objects to fall toward the presumed largest object in the video game world: the world itself.
### Adding a gravity function
Remember that your player already has a property to determine motion. Use this property to pull the player sprite toward the bottom of the screen.
In Pygame, higher numbers are closer to the bottom edge of the screen.
In the real world, gravity affects everything. In platformers, however, gravity is selective—if you add gravity to your entire game world, all of your platforms would fall to the ground. Instead, you add gravity just to your player and enemy sprites.
First, add a **gravity** function in your **Player** class:
```
    def gravity(self):
        self.movey += 3.2 # how fast player falls
```
This is a simple function. First, you set your player in vertical motion, whether your player wants to be in motion or not. In other words, you have programmed your player to always be falling. That's basically gravity.
For the gravity function to have an effect, you must call it in your main loop. This way, Python applies the falling motion to your player once every clock tick.
In this code, add the first line to your loop:
```
    player.gravity() # check gravity
    player.update()
```
Launch your game to see what happens. Look sharp, because it happens fast: your player falls out of the sky, right off your game screen.
Your gravity simulation is working, but maybe too well.
As an experiment, try changing the rate at which your player falls.
### Adding a floor to gravity
The problem with your character falling off the world is that there's no way for your game to detect it. In some games, if a player falls off the world, the sprite is deleted and respawned somewhere new. In other games, the player loses points or a life. Whatever you want to happen when a player falls off the world, you have to be able to detect when the player disappears offscreen.
In Python, to check for a condition, you can use an **if** statement.
You must check to see **if** your player is falling and how far your player has fallen. If your player falls so far that it reaches the bottom of the screen, then you can do _something_. To keep things simple, set the position of the player sprite to 20 pixels above the bottom edge.
Make your **gravity** function look like this:
```
    def gravity(self):
        self.movey += 3.2 # how fast player falls
       
        if self.rect.y &gt; worldy and self.movey &gt;= 0:
            self.movey = 0
            self.rect.y = worldy-ty
```
Then launch your game. Your sprite still falls, but it stops at the bottom of the screen. You may not be able to _see_ your sprite behind the ground layer, though. An easy fix is to make your player sprite bounce higher by adding another **-ty** to its new Y position after it hits the bottom of the game world:
```
    def gravity(self):
        self.movey += 3.2 # how fast player falls
       
        if self.rect.y &gt; worldy and self.movey &gt;= 0:
            self.movey = 0
            self.rect.y = worldy-ty-ty
```
Now your player bounces at the bottom of the screen, just behind your ground sprites.
What your player really needs is a way to fight gravity. The problem with gravity is, you can't fight it unless you have something to push off of. So, in the next article, you'll add ground and platform collision and the ability to jump. In the meantime, try applying gravity to the enemy sprite.
Here's all the code so far:
```
#!/usr/bin/env python3
# draw a world
# add a player and player control
# add player movement
# add enemy and basic collision
# add platform
# add gravity
# GNU All-Permissive License
# Copying and distribution of this file, with or without modification,
# are permitted in any medium without royalty provided the copyright
# notice and this notice are preserved.  This file is offered as-is,
# without any warranty.
import pygame
import sys
import os
'''
Objects
'''
class Platform(pygame.sprite.Sprite):
    # x location, y location, img width, img height, img file    
    def __init__(self,xloc,yloc,imgw,imgh,img):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load(os.path.join('images',img)).convert()
        self.image.convert_alpha()
        self.rect = self.image.get_rect()
        self.rect.y = yloc
        self.rect.x = xloc
class Player(pygame.sprite.Sprite):
    '''
    Spawn a player
    '''
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.movex = 0
        self.movey = 0
        self.frame = 0
        self.health = 10
        self.score = 1
        self.images = []
        for i in range(1,9):
            img = pygame.image.load(os.path.join('images','hero' + str(i) + '.png')).convert()
            img.convert_alpha()
            img.set_colorkey(ALPHA)
            self.images.append(img)
            self.image = self.images[0]
            self.rect  = self.image.get_rect()
    def gravity(self):
        self.movey += 3.2 # how fast player falls
       
        if self.rect.y &gt; worldy and self.movey &gt;= 0:
            self.movey = 0
            self.rect.y = worldy-ty-ty
       
    def control(self,x,y):
        '''
        control player movement
        '''
        self.movex += x
        self.movey += y
       
    def update(self):
        '''
        Update sprite position
        '''
        self.rect.x = self.rect.x + self.movex
        self.rect.y = self.rect.y + self.movey
        # moving left
        if self.movex &lt; 0:
            self.frame += 1
            if self.frame &gt; ani*3:
                self.frame = 0
            self.image = self.images[self.frame//ani]
        # moving right
        if self.movex &gt; 0:
            self.frame += 1
            if self.frame &gt; ani*3:
                self.frame = 0
            self.image = self.images[(self.frame//ani)+4]
        # collisions
        enemy_hit_list = pygame.sprite.spritecollide(self, enemy_list, False)
        for enemy in enemy_hit_list:
            self.health -= 1
            print(self.health)
        ground_hit_list = pygame.sprite.spritecollide(self, ground_list, False)
        for g in ground_hit_list:
            self.health -= 1
            print(self.health)
class Enemy(pygame.sprite.Sprite):
    '''
    Spawn an enemy
    '''
    def __init__(self,x,y,img):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load(os.path.join('images',img))
        #self.image.convert_alpha()
        #self.image.set_colorkey(ALPHA)
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y
        self.counter = 0
       
    def move(self):
        '''
        enemy movement
        '''
        distance = 80
        speed = 8
        if self.counter &gt;= 0 and self.counter &lt;= distance:
            self.rect.x += speed
        elif self.counter &gt;= distance and self.counter &lt;= distance*2:
            self.rect.x -= speed
        else:
            self.counter = 0
        self.counter += 1
class Level():
    def bad(lvl,eloc):
        if lvl == 1:
            enemy = Enemy(eloc[0],eloc[1],'yeti.png') # spawn enemy
            enemy_list = pygame.sprite.Group() # create enemy group
            enemy_list.add(enemy)              # add enemy to group
           
        if lvl == 2:
            print("Level " + str(lvl) )
        return enemy_list
    def loot(lvl,lloc):
        print(lvl)
    def ground(lvl,gloc,tx,ty):
        ground_list = pygame.sprite.Group()
        i=0
        if lvl == 1:
            while i &lt; len(gloc):
                ground = Platform(gloc[i],worldy-ty,tx,ty,'ground.png')
                ground_list.add(ground)
                i=i+1
        if lvl == 2:
            print("Level " + str(lvl) )
        return ground_list
    def platform(lvl,tx,ty):
        plat_list = pygame.sprite.Group()
        ploc = []
        i=0
        if lvl == 1:
            ploc.append((0,worldy-ty-128,3))
            ploc.append((300,worldy-ty-256,3))
            ploc.append((500,worldy-ty-128,4))
            while i &lt; len(ploc):
                j=0
                while j &lt;= ploc[i][2]:
                    plat = Platform((ploc[i][0]+(j*tx)),ploc[i][1],tx,ty,'ground.png')
                    plat_list.add(plat)
                    j=j+1
                print('run' + str(i) + str(ploc[i]))
                i=i+1
        if lvl == 2:
            print("Level " + str(lvl) )
        return plat_list
'''
Setup
'''
worldx = 960
worldy = 720
fps = 40 # frame rate
ani = 4  # animation cycles
clock = pygame.time.Clock()
pygame.init()
main = True
BLUE  = (25,25,200)
BLACK = (23,23,23 )
WHITE = (254,254,254)
ALPHA = (0,255,0)
world = pygame.display.set_mode([worldx,worldy])
backdrop = pygame.image.load(os.path.join('images','stage.png')).convert()
backdropbox = world.get_rect()
player = Player() # spawn player
player.rect.x = 0
player.rect.y = 0
player_list = pygame.sprite.Group()
player_list.add(player)
steps = 10 # how fast to move
eloc = []
eloc = [200,20]
gloc = []
#gloc = [0,630,64,630,128,630,192,630,256,630,320,630,384,630]
tx = 64 #tile size
ty = 64 #tile size
i=0
while i &lt;= (worldx/tx)+tx:
    gloc.append(i*tx)
    i=i+1
enemy_list = Level.bad( 1, eloc )
ground_list = Level.ground( 1,gloc,tx,ty )
plat_list = Level.platform( 1,tx,ty )
'''
Main loop
'''
while main == True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit(); sys.exit()
            main = False
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT or event.key == ord('a'):
                print("LEFT")
                player.control(-steps,0)
            if event.key == pygame.K_RIGHT or event.key == ord('d'):
                print("RIGHT")
                player.control(steps,0)
            if event.key == pygame.K_UP or event.key == ord('w'):
                print('jump')
        if event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT or event.key == ord('a'):
                player.control(steps,0)
            if event.key == pygame.K_RIGHT or event.key == ord('d'):
                player.control(-steps,0)
            if event.key == pygame.K_UP or event.key == ord('w'):
                print('jump')
            if event.key == ord('q'):
                pygame.quit()
                sys.exit()
                main = False
    world.blit(backdrop, backdropbox)
    player.gravity() # check gravity
    player.update()
    player_list.draw(world)
    enemy_list.draw(world)
    ground_list.draw(world)
    plat_list.draw(world)
    for e in enemy_list:
        e.move()
    pygame.display.flip()
    clock.tick(fps)
```
* * *
This is part 6 in an ongoing series about creating video games in [Python 3][3] using the [Pygame][4] module. Previous articles are:
* [Learn how to program in Python by building a simple dice game][5]
* [Build a game framework with Python using the Pygame module][6]
* [How to add a player to your Python game][7]
* [Using Pygame to move your game character around][8]
* [What's a hero without a villain? How to add one to your Python game][2]
--------------------------------------------------------------------------------
via: https://opensource.com/article/19/11/simulate-gravity-python
作者:[Seth Kenlon][a]
选题:[lujun9972][b]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/seth
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/space_stars_cosmic.jpg?itok=bE94WtN- (Cosmic stars in outer space)
[2]: https://opensource.com/article/18/5/pygame-enemy
[3]: https://www.python.org/
[4]: https://www.pygame.org
[5]: https://opensource.com/article/17/10/python-101
[6]: https://opensource.com/article/17/12/game-framework-python
[7]: https://opensource.com/article/17/12/game-python-add-a-player
[8]: https://opensource.com/article/17/12/game-python-moving-player

View File

@ -0,0 +1,170 @@
[#]: collector: (lujun9972)
[#]: translator: (geekpi)
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (How containers work: overlayfs)
[#]: via: (https://jvns.ca/blog/2019/11/18/how-containers-work--overlayfs/)
[#]: author: (Julia Evans https://jvns.ca/)
容器如何工作overlayfs
======
今天早上,我在未来潜在容器[杂志][1]上画了一幅 overlay 文件系统漫画,我对这个主题感到兴奋,想写一篇关于它的博客来提供更多详细信息。下面是漫画:
<https://jvns.ca/images/overlay.jpeg>
### 容器镜像很大
容器镜像可能会很大(尽管有些很小,例如 [alpine linux 是 2.5MB][2]。Ubuntu 16.04 约为 27 MB[Anaconda Python 发行版为 800MB 至 1.5GB][3]。
你以镜像启动的每个容器都是原始空白状态,仿佛它只是为使用容器而复制的一份镜像拷贝一样。但是对于大的容器镜像,像 800MB 的 Anaconda 镜像,复制一份拷贝既浪费磁盘空间也很慢。因此 Docker 不会复制,而是采用**叠加**。
### 叠加如何工作
overlayfs也被称为 **Union 文件系统**或 **Union 挂载** 它可让你使用 2 个目录挂载文件系统:“下层”目录和“上层”目录。
基本上:
* 文件系统的**下层**目录是只读的
* 文件系统的**上层**目录可以读写
当进程“读取”文件时overlayfs 文件系统驱动将在上层目录中查找并从该目录中读取文件(如果存在)。否则,它将在下层目录中查找。
当进程“写入”文件时overlayfs 会将其写入上层目录。
### 让我们使用 `mount` 制造一个叠加层!
这有点抽象,所以让我们制作一个 overlayfs 并尝试一下!这将只包含一些文件:我将创建上,下层目录,并将合并的文件系统挂载到的`合并`目录:
```
$ mkdir upper lower merged work
$ echo "I'm from lower!" > lower/in_lower.txt
$ echo "I'm from upper!" > upper/in_upper.txt
$ # `in_both` is in both directories
$ echo "I'm from lower!" > lower/in_both.txt
$ echo "I'm from upper!" > upper/in_both.txt
```
合并上层目录和下层目录非常容易:我们可以通过 `mount` 来完成!
```
$ sudo mount -t overlay overlay
-o lowerdir=/home/bork/test/lower,upperdir=/home/bork/test/upper,workdir=/home/bork/test/work
/home/bork/test/merged
```
在执行此操作时,我不断收到一条非常烦人的错误消息,内容为:`mount: /home/bork/test/merged: special device overlay does not exist.`。这条消息是错误的,实际上只是意味着我指定的一个目录缺失(我写成了 `~/test/merged`,但它没有被扩展)。
让我们尝试从 overlayfs 中读取其中一个文件!文件 `in_both.txt` 同时存在于 `lower/``upper/` 中,因此应从 `upper/` 目录中读取该文件。
```
$ cat merged/in_both.txt
"I'm from upper!
```
可以成功!
目录的内容就是我们所期望的:
```
find lower/ upper/ merged/
lower/
lower/in_lower.txt
lower/in_both.txt
upper/
upper/in_upper.txt
upper/in_both.txt
merged/
merged/in_lower.txt
merged/in_both.txt
merged/in_upper.txt
```
### 创建新文件时会发生什么?
```
$ echo 'new file' > merged/new_file
$ ls -l */new_file
-rw-r--r-- 1 bork bork 9 Nov 18 14:24 merged/new_file
-rw-r--r-- 1 bork bork 9 Nov 18 14:24 upper/new_file
```
这是有作用的,新文件会在 `upper` 目录创建。
### 删除文件时会发生什么?
读写似乎很简单。但是删除会发生什么?开始试试!
```
$ rm merged/in_both.txt
```
发生了什么?让我们用 `ls` 看下:
```
ls -l upper/in_both.txt lower/lower1.txt merged/lower1.txt
ls: cannot access 'merged/in_both.txt': No such file or directory
-rw-r--r-- 1 bork bork 6 Nov 18 14:09 lower/in_both.txt
c--------- 1 root root 0, 0 Nov 18 14:19 upper/in_both.txt
```
所以:
* `in_both.txt` 仍在 `lower` 目录中,并且保持不变
* 它不在 `merged` 目录中。到目前为止,这就是我们所期望的。
* 但是在 `upper` 中发生的事情有点奇怪:有一个名为 `upper/in_both.txt` 的文件,但是它是字符设备?我想这就是 overlayfs 驱动表示删除的文件的方式。
如果我们尝试复制这个奇怪的字符设备文件,会发生什么?
```
$ sudo cp upper/in_both.txt upper/in_lower.txt
cp: cannot open 'upper/in_both.txt' for reading: No such device or address
```
好吧,这似乎很合理,复制这个奇怪的删除信号文件并没有任何意义。
### 你可以挂载多个“下层”目录
Docker 镜像通常由 25 个“层”组成。overlayfs 支持具有多个下层目录,因此你可以运行
```
mount -t overlay overlay
-o lowerdir:/dir1:/dir2:/dir3:...:/dir25,upperdir=...
```
因此,我假设这是有多个 Docker 层的容器的工作方式,它只是将每个层解压缩到一个单独的目录中,然后要求 overlayfs 将它们全部合并在一起,并使用一个空的上层目录,容器将对其进行更改。
### Docker 也可以使用 btrfs 快照
现在,我使用的是 ext4而 Docker 使用 overlayfs 快照来运行容器。但是我曾经用过 btrfs接着 Docker 将改为使用 btrfs 的写时复制快照。 (这是 Docker 何时使用哪种[存储驱动][4]的列表)
以这种方式使用 btrfs 快照会产生一些有趣的结果-去年某个时候,我在笔记本上运行了数百个临时的 Docker 容器,这导致我用尽了 btrfs 元数据空间(像[这个人][5])。这真的很令人困惑,因为我以前从未听说过 btrfs 元数据,而且弄清楚如何清理文件系统以便再次运行 Docker 容器非常棘手。([这个 docker github 上的问题][6]描述了 Docker 和 btrfs 的类似问题)
### 以简单的方式尝试容器功能很有趣!
我认为容器通常看起来像是在做“复杂的”事情,我认为将它们分解成这样很有趣。你可以运行一条 `mount` 咒语,而实际上并没有做任何与容器相关的其他事情,看看叠加层是如何工作的!
--------------------------------------------------------------------------------
via: https://jvns.ca/blog/2019/11/18/how-containers-work--overlayfs/
作者:[Julia Evans][a]
选题:[lujun9972][b]
译者:[geekpi](https://github.com/geekpi)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://jvns.ca/
[b]: https://github.com/lujun9972
[1]: https://wizardzines.com
[2]: https://hub.docker.com/_/alpine?tab=tags
[3]: https://hub.docker.com/r/continuumio/anaconda3/tags
[4]: https://docs.docker.com/storage/storagedriver/select-storage-driver/
[5]: https://www.reddit.com/r/archlinux/comments/5jrmfe/btrfs_metadata_and_docker/
[6]: https://github.com/moby/moby/issues/27653