清除过期文章

This commit is contained in:
Xingyu Wang
2023-07-02 09:58:11 +08:00
parent 46ee6e50c9
commit e09edd5153
271 changed files with 0 additions and 52859 deletions

View File

@@ -1,74 +0,0 @@
[#]: subject: (Linux powers the internet, confirms EU commissioner)
[#]: via: (https://opensource.com/article/21/3/linux-powers-internet)
[#]: author: (James Lovegrove https://opensource.com/users/jlo)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
Linux powers the internet, confirms EU commissioner
======
EU celebrates the importance of open source software at the annual EU
Open Source Policy Summit.
![Penguin driving a car with a yellow background][1]
In 20 years of EU digital policy in Brussels, I have seen growing awareness and recognition among policymakers in Europe of the importance of open source software (OSS). A recent keynote by EU internal market commissioner Thierry Breton at the annual [EU Open Source Policy Summit][2] in February provides another example—albeit with a sense of urgency and strategic opportunity that has been largely missing in the past.
Commissioner Breton did more than just recognize the "long list of [OSS] success stories." He also underscored OSS's critical role in accelerating Europe's €750 billion recovery and the goal to further "embed open source" into Europe's longer-term policy objectives in the public sector and other key industrial sectors.
In addition to the commissioner's celebration that "Linux is powering the internet," there was a policy-related call to action to expand the OSS value proposition to many other areas of digital sovereignty. Indeed, with only 2.5 years of EU Commission mandate remaining, there is a welcome sense of urgency. I see three possible reasons for this: 1. fresh facts and figures, 2. compelling policy commitments, and 3. game-changing investment opportunities for Europe.
### 1\. Fresh facts and figures
Commissioner Breton shared new facts and figures to better inform policymakers in Brussels and all European capitals. The EU's new [Open Source Study][3] reveals that the "economic impact of OSS is estimated to have been between €65 and €95 billion (2018 figures)" and an "increase of 10% [in code contributions] would generate in the future around additional €100 billion in EU GDP per year."
This EU report on OSS, the first since 2006, builds nicely on several other recent open source reports in Germany (from [Bitkom][4]) and France (from [CNLL/Syntec][5]), recent strategic IT analysis by the German federal government, and the [Berlin Declaration][6]'s December 2020 pledge for all EU member states to "implement common standards, modular architectures, and—when suitable—open source technologies in the development and deployment of cross-border digital solutions" by 2024, the end of current EU Commission's mandate.
### 2\. Compelling policy commitments
Commissioner Breton's growth and sovereignty questions seemed to hinge on the need to bolster existing open source adoption and collaboration—notably "how to embed open source into public administration to make them more efficient and resilient" and "how to create an enabling framework for the private sector to invest in open source."
I would encourage readers to review the various [panel discussions][7] from the Policy Summit that address many of the important enabling factors (e.g., establishing open source program offices [OSPOs], open standards, public sector sharing and reuse, etc.). These will be tackled over the coming months with deeper dives by OpenForum Europe and other European associations (e.g., Bitkom's Open Source Day on 16 September), thereby bringing policymaking and open source code and collaboration closer together.
### 3\. Game-changing investments
The European Parliament [recently approved][8] the final go-ahead for the €750 billion Next Generation European Union ([NGEU][9]) stimulus package. This game-changing investment is a once-in-a-generation opportunity to realize longstanding EU policy objectives while accelerating digital transformation in an open and sustainable fashion, as "each plan has to dedicate at least 37% of its budget to climate and at least 20% to digital actions."
During the summit, great insights into how Europe's public sector can further embrace open innovation in the context of these game-changing EU funds were shared by [OFE][10] and [Digital Europe][11] speakers from Germany, Italy, Portugal, Slovenia, FIWARE, and Red Hat. 2021 is fast becoming a critical year when this objective can be realized within the public sector and [industry][12].
### A call to action
Commissioner Breton's recognition of Linux is more than another political validation that "open source has won." It is a call to action to collaborate to accelerate European competitiveness and transformation and is a key to sovereignty (interoperability within services and portability of data and workloads) to reflect key European values through open source.
Commissioner Breton is working closely with the EU executive vice president for a digital age, Margate Vestager, to roll out a swathe of regulatory carrots and sticks for the digital sector. Indeed, in the words of the Commission President Ursula von der Leyen at the recent [Masters of Digital 2021][13] event, "this year we are rewriting the rule book for our digital internal market. I want companies to know that across the European Union, there will be one set of digital rules instead of this patchwork of national rules."
In another 10 years, we will all look back on the past year and ask ourselves this question: did we "waste a good crisis" to realize [Europe's digital decade][14]?
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/3/linux-powers-internet
作者:[James Lovegrove][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/jlo
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/car-penguin-drive-linux-yellow.png?itok=twWGlYAc (Penguin driving a car with a yellow background)
[2]: https://openforumeurope.org/event/policy-summit-2021/
[3]: https://ec.europa.eu/digital-single-market/en/news/study-and-survey-impact-open-source-software-and-hardware-eu-economy
[4]: https://www.bitkom.org/Presse/Presseinformation/Open-Source-deutschen-Wirtschaft-angekommen
[5]: https://joinup.ec.europa.eu/collection/open-source-observatory-osor/news/technological-independence
[6]: https://www.bmi.bund.de/SharedDocs/downloads/EN/eu-presidency/gemeinsame-erklaerungen/berlin-declaration-digital-society.html
[7]: https://www.youtube.com/user/openforumeurope/videos
[8]: https://www.europarl.europa.eu/news/en/press-room/20210204IPR97105/parliament-gives-go-ahead-to-EU672-5-billion-recovery-and-resilience-facility
[9]: https://ec.europa.eu/info/strategy/recovery-plan-europe_en
[10]: https://www.youtube.com/watch?v=xU7cfhVk3_s&feature=emb_logo
[11]: https://www.youtube.com/watch?v=Jq3s6cdsA0I&feature=youtu.be
[12]: https://www.digitaleurope.org/wp/wp-content/uploads/2021/02/DIGITALEUROPE-recommendations-on-the-Update-to-the-EU-Industrial-Strategy_Industrial-Forum-questionnaire-comms.pdf
[13]: https://www.youtube.com/watch?v=EDzQI7q2YKc
[14]: https://ec.europa.eu/info/law/better-regulation/have-your-say/initiatives/12900-Europe-s-digital-decade-2030-digital-targets

View File

@@ -1,130 +0,0 @@
[#]: subject: (What Google v. Oracle means for open source)
[#]: via: (https://opensource.com/article/21/5/google-v-oracle)
[#]: author: (Jeffrey Robert Kaufman https://opensource.com/users/jkaufman)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
What Google v. Oracle means for open source
======
The Supreme Court's decision adds clarity around the fair use of APIs
that will help software developers.
![Two government buildings][1]
Google v. Oracle has finally concluded in a sweeping [6-2 decision by the US Supreme Court][2] favoring Google and adding further clarity on the freedom to use application programming interfaces (APIs). Software developers can benefit from this decision.
The open source community has closely followed the litigation between Google and Oracle due to its potential impact on the reuse of APIs. It has been assumed for many decades that APIs are not protected by copyright and are free to use by anyone to both create new and improved software modules and to integrate with existing modules that use such interfaces.
This case involves Google's use of a certain portion of the API from Oracle's Java SE when Google created Android. This case went through over 10 years of protracted litigation in the lower courts. The US Court of Appeals for the Federal Circuit (CAFC) had previously held that 1) Oracle's copyright in a portion of the Java SE API copied by Google was copyrightable, and 2) Google's use was not excused as fair use under the law. This meant that Google would have been liable for copyright infringement for that portion of Oracle's Java SE API used in Android. If this holding were left to stand, it would not only have been a loss for Google but also for the software development community, including open source.
Unrestricted use of APIs has been the norm for decades and a key driver of innovation, including the modern internet and countless software modules and devices that communicate with each other using such interfaces. The fact is, the software industry was rarely concerned about the use of APIs until Oracle decided to make a federal case about it.
It is unfortunate that the software industry was put through this turmoil for over a decade. However, the Supreme Court's decision provides a new explanation and framework for analyzing use of software interfaces, and it is largely good news. In short, while the court did not overturn the copyrightability ruling, which would have been the best news from the perspective of software developers, it ruled strongly in favor of Google on whether Google's use was a fair use as a matter of law.
### What is an API? It depends who you ask
Before I begin a more detailed description of this case and what the result means for software developers, I need to define an API. This is a significant source of confusion and made worse by the court adopting a definition that does not reflect the conventional meaning.
The Supreme Court uses the following diagram to describe what it refers to as an API:
![Sun Java API diagram][3]
(Source: Google LLC v. Oracle America, Inc., [No. 18-956][2], US Apr. 5, 2021; pg. 38)
In the court's definition, an API includes both "declaring code" and "implementing code"—terms adopted by the court, although they are not used by developers in Java or other programming languages. The declaring code (what Java developers call the method declaration) declares the name of the method and its inputs and outputs. In the example above, the declaring code declares the method name, "max," and further declares that it receives two integers, "x" and "y," and returns an integer of the result.
Implementing code (what Java developers call the method body) consists of instructions that implement the functions of the method. So in the example above, the implementing code would use computer instructions and logic to determine whether x or y is the larger number and return the larger number.
At issue in this case was the declaring code only. Google was accused of copying portions of the declaring code of Java SE for use in Android and the "structure, sequence, and organization" of that declaring code. In the final stages of this case, Google was not accused of copying any implementing code. The parties in the case acknowledged that Google wrote its own implementing code for Android.
The declaring code is what most people would refer to as an API; not the court's definition of an API that combines the declaring code and implementing code. The declaring code is, in essence, a "software interface" allowing access to a software module's various methods. Said another way, it allows one software module to interface, pass information to/from, and control another software module.
I will refer to the declaring code as a "software interface," as that is what concerns the industry in this case. Software interfaces under this definition exclude any implementing code.
### Now, with that out the way….
Here is a more detailed explanation of what the Supreme Court case specifically means.
Google was accused of copying certain declaring code of Java SE for use in Android. Not only did it copy the names of many of the methods but, in doing so, it copied the structure, sequence, and organization of that declaring code (e.g., how the code was organized into packages, classes, and the like). Structure, sequence, and organization (SSO) may be protectable under US copyright law. This case bounced around the courts for many years, and the history is fascinating for legal scholars. However, for our purposes, I'll just cut to the chase.
If a work is not protected by copyright, then it generally may be used without restriction. Google argued strenuously that the declaring code it copied was just that—not protectable by copyright. Arguments to support its non-copyrightability include that it is an unprotectable method or system of operation that is clearly written in US copyright laws as outside the scope of protection. In fact, this is an argument Red Hat and IBM made in their ["friend of the court" brief][4] filed with the Supreme Court in January 2020. If the court held that the declaring code copied by Google was not copyrightable, this would have been the end of the story and the absolute best situation for the developer community.
Unfortunately, we did not get that from the court, but we got the next best thing.
As a corollary to what I just said, you may get yourself in legal jeopardy by copying or modifying someone else's copyrighted work, such as a book, picture, or even software, without permission from the copyright owner. This is because the owner of the copyrighted work has the exclusive right to copy and make changes (also known as derivative works). So unless you have a license (which could be an open source license or a proprietary license) or a fair use defense, you cannot copy or change someone else's copyrighted work. Fair use is a defense to using someone's copyrighted work, which I'll discuss shortly.
The good news is that the Supreme Court did not rule that Oracle's declaring code was copyrightable. It explicitly chose to sidestep this question and to decide the case on narrower grounds. But it also seemed to indicate support for the position that declaring code, if copyrightable at all, is further from what the court considers to be the core of copyright.[1][5] It is possible that future lower courts may hold that software interfaces are not copyrightable. (See the end of this article for a fuller description of this issue.) This is good news.
What the Supreme Court did instead is to assume for argument's sake that Oracle had a valid copyright on the declaring code (i.e., software interface) and, on this basis, it asked whether Google's use was a fair-use defense. The result was a resounding yes!
### When is fair use fair?
The Supreme Court decision held that Google's use of portions of Java SE declaring code is fair use. Fair use is a defense to copyright infringement in that if you are technically violating someone's copyright, your use may be excused under fair use. Academia is one example (among many) where fair use can provide a strong defense in many cases.
This is where the court began to analyze each factor of fair use to see if and how it could apply to Google's situation. Being outside academia, where it is relatively easier to decide such issues, this situation required a more careful analysis of each of the fair-use factors under the law.
Fair use is a factor test. There are four factors described in US copyright law that are used to determine whether fair use is applicable (although other factors can also be considered by the court). For a fuller description of fair use, see this [article by the US Copyright Office][6]. The tricky thing with fair use is that not all factors need to be present, and one factor may not have as much weight as another. Some factors may even be related and push and pull against each other, depending on the facts in the case. The fortunate result of the Supreme Court decision is it decided in favor of Google on fair use on all four of the statutory factors and in a 6-2 decision. This is not a situation that was right on the edge; far from it.
### Implications for software developers
Below, I will provide my perspective on what a software developer or attorney should consider when evaluating whether the reuse of a software interface is fair use under the law. This perspective is based on the recent Supreme Court ruling. The following should serve as guideposts to help you provide more opportunities for a court to view your use as fair use in the unlikely scenario that 1) your use of a software interface is ever challenged, and 2) that the software interface is held to be copyrightable…which it may never be since the Supreme Court did not hold that they are copyrightable. It instead leaves this question to the lower courts to decide.
Before I jump into this, a brief discussion of use cases is in order.
There are two major use cases for software interface usage. In the Google case, it was reimplementing portions of the Java SE software interface for Android. This means it kept the same declaring code and rewrote all of the applicable implementation code for each method declaration. I refer to that as "reimplementation," and it is akin to the right side of the diagram above used in the Supreme Court decision. This is very common in the open source community: a module has a software interface that many other software systems and modules may utilize, and a creative developer improves that module by creating new and improved implementations in the form of new implementing code. By using the same declaring code for each improved method, the preexisting software systems and modules may use the improved module without rewriting any of the code, or perhaps doing minimal rewriting. This is a huge benefit and supercharges the open source development ecosystem.
A second common use case, shown on the left side of the diagram, uses a software interface to enable communication and control between one software module and another. This allows one module to invoke the various methods in another module using that software interface. Although this second use case was not specifically addressed in the Supreme Court decision, it is my view that such use may have an even stronger argument for non-copyrightability and a fair-use defense in all but the most unusual circumstances.
### 4 tips for complying with fair use
Whether you are simply using a software interface to effectuate control and communication to another software module or reimplementing an existing software module with your own new and improved implementation code, the following guidelines will help you maintain your usage within fair use based on the Supreme Court's latest interpretation.
1. For both use cases described above, use no more of the software interface than what is required to enable interaction with another software module. Also, be aware of how much of the work you are copying. The less you copy of the whole, the greater the weight of this fair-use factor bends in your favor.
2. Write your own implementation code when reimplementing and improving an existing module.
3. Avoid using any of the other module's implementation code, except any declaring code that may have been replicated in whole or in part in the other module's implementation code. This happens sometimes, and it is often unavoidable.
4. Make your implementation as transformative as possible. This means adding something new with a further purpose or different character. In Google's situation, it transformed portions of Java SE to be better utilized in a mobile environment. This was seen as a factor in the case.
### Can APIs be copyrighted?
So what about copyrightability of APIs and this odd situation of the Supreme Court not ruling on the issue? Does this mean that APIs are actually copyrightable? Otherwise, why do we have to do a fair-use analysis? Excellent questions!
The answer is maybe, but in my view, unlikely in most jurisdictions. In a weird quirk, this case was appealed from the initial trial court to the CAFC and not to the 9th US Circuit Court of Appeals, which would have been the traditional route of appeal for cases heard in the San Francisco-based trial court. The CAFC does not ordinarily hear copyright cases like Oracle v. Google.[2][7] While the CAFC applied 9th Circuit law in deciding the case, the 9th Circuit should not be bound by that decision.
There are 13 federal appellate courts in the United States. So although the CAFC (but not the US Supreme Court) decided that software interfaces are protected by copyright, its decision is not binding on other appellate courts or even on the CAFC, except in the rare circumstance where the CAFC is applying 9th Circuit law. The decision, however, could be "persuasive" in other cases examining copyrightability in the 9th Circuit. There is only a very small subset of cases and situations where the CAFC ruling on copyrightability would be binding in our appellate court system.
_But even if the CAFC hears a case on software interfaces based on 9th (or another) Circuit law and decides that a certain software interface is protected by copyright under such law, we still have this very broad and powerful Supreme Court decision that provides a clear framework and powerful message on the usefulness of the fair-use doctrine as a viable defense to such use._
Will your use of another's software interface ever be challenged? As I stated, reuse of software interfaces has been going on for decades with little fanfare until this case.
* * *
1. “In our view, ... the declaring code is, if copyrightable at all, further than are most computer programs (such as the implementing code) from the core of copyright.”  Google LLC v. Oracle America, Inc., No. 18-956, (US, Apr. 5, 2021)
2. The CAFC heard the case only because it was originally tied to a patent claim, which eventually dropped off the case. If not for the patent claim, this case would have been heard by the 9th Circuit Court of Appeals.
Web APIs have become ubiquitous in the industry, but many organizations are struggling to create...
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/5/google-v-oracle
作者:[Jeffrey Robert Kaufman][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/jkaufman
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/LAW_lawdotgov2.png?itok=n36__lZj (Two government buildings)
[2]: https://www.supremecourt.gov/opinions/20pdf/18-956_d18f.pdf
[3]: https://opensource.com/sites/default/files/uploads/supremecourt_api_definition.png (Sun Java API diagram)
[4]: https://www.redhat.com/en/blog/red-hat-statement-us-supreme-court-decision-google-v-oracle
[5]: tmp.gvGY7lfUHR#1
[6]: https://www.copyright.gov/title17/92chap1.html#107
[7]: tmp.gvGY7lfUHR#2

View File

@@ -1,97 +0,0 @@
[#]: subject: "This Game Developer Loves the Linux Community for an Unusual Reason"
[#]: via: "https://news.itsfoss.com/game-dev-loves-linux/"
[#]: author: "Ankush Das https://news.itsfoss.com/author/ankush/"
[#]: collector: "lujun9972"
[#]: translator: " "
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
This Game Developer Loves the Linux Community for an Unusual Reason
======
The Linux community, in general, is one of the most active and helpful communities out there.
And, a significant chunk of that can also be toxic or aggressive to newbies or someone who tries to break traditions.
However, a game developer seems to be appreciating the Linux community for complaining too much…
Yes, you heard that right! But, thats not the entire picture. Let me tell you more about it.
### Reporting Bugs is Essential for Game Improvement
Whether it is an indie game or a full-fledged AAA title, every game arrives with several bugs.
For some studios, game testers try to spot the bugs before launch. But, no matter the effort, players will always notice something that the developers may not have.
So, it is important for developers to work on the reported bugs for a better gaming experience.
But, what if you do not get any bug reports even if the game encounters issues?
Of course, you can invest a lot of time to find out the potential issues faced by players. Unfortunately, it is not possible to iron out everything yourself.
This is why bug reports from players are an essential part of game development.
And, to emphasize the importance of bug reports, the game developer of “**[ΔV: Rings of Saturn][1]**” shared some interesting information.
### Linux Gamers Reported Over 38% Bug Reports With 5.8% Userbase
![][2]
Even though [gaming on Linux][3] is improving with the [addition of Easy Anti-Cheat, BattleEye][4], and many other new advancements, the user base is tiny when compared to Windows.
However, the developer of “**ΔV: Rings of Saturn**” shares an insight where he mentions that out of all the players, Linux gamers reported a significant section of bugs considering the user base.
![][5]
Heres what he said in a [Reddit thread][6]:
> Percentages are easy to talk about, but when I read just them, I always wonder what is the sample size? Is it small enough for the percentage to be just noise?
>
> As of today, I sold a little over 12,000 units of ΔV in total. 700 of these units were bought by Linux players.
>
> Thats 5.8%. I got 1040 bug reports in total, out of which roughly 400 are made by Linux players. Thats one report per 11.5 users on average, and one report per 1.75 Linux players. Thats right, an average Linux player will get you 650% more bug reports.
Not just limited to the number of bug reports, most of the issues reported were well-detailed and could be reproduced or isolated with the details provided.
So, the minority group of Linux gamers turns out to be more valuable in terms of giving feedback and helping improve the game compared to Windows users.
Also, the issues spotted were hardly platform-specific. So, these reports will equally help gamers using Windows to play the game as well.
The game developer adds:
> Its worth it to get the massive feedback boost and free, hundred-people strong QA team on your side. An invaluable asset for an independent game studio.
Of course, no gamer is obliged to report errors in a game. But, this example highlighted by the game developer goes to show how passionate the Linux community can be along with the importance of bug reports.
### Closing Thoughts
Overall, I believe that you can always count on the Linux community. While some can be toxic, the majority of the users work towards helping each other and growing together as Linux users.
What do you think about this particular insight of Linux users reporting more bug reports despite the number of users? Please dont hesitate to share your thoughts in the comments down below.
#### Big Tech Websites Get Millions in Revenue, It's FOSS Got You!
If you like what we do here at It's FOSS, please consider making a donation to support our independent publication. Your support will help us keep publishing content focusing on desktop Linux and open source software.
I'm not interested
--------------------------------------------------------------------------------
via: https://news.itsfoss.com/game-dev-loves-linux/
作者:[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://news.itsfoss.com/author/ankush/
[b]: https://github.com/lujun9972
[1]: https://store.steampowered.com/app/846030/V_Rings_of_Saturn/
[2]: data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjQzOSIgd2lkdGg9Ijc4MCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjEiLz4=
[3]: https://itsfoss.com/linux-gaming-guide/
[4]: https://news.itsfoss.com/easy-anti-cheat-linux/
[5]: data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjUzNiIgd2lkdGg9Ijc2MyIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjEiLz4=
[6]: https://www.reddit.com/r/gamedev/comments/qeqn3b/despite_having_just_58_sales_over_38_of_bug/

View File

@@ -1,112 +0,0 @@
[#]: subject: "Global communication in open source projects"
[#]: via: "https://opensource.com/article/21/10/global-communication-open-source"
[#]: author: "Rachel Naegele https://opensource.com/users/ranaegele"
[#]: collector: "lujun9972"
[#]: translator: " "
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
Global communication in open source projects
======
An interview with FreeDOS Project founder Jim Hall on communicating
effectively around the world.
![Globe up in the clouds][1]
I am a current graduate student at the University of Minnesota, Twin Cities in the Scientific and Technical Communication MS program. The following is an interview I conducted with [Jim Hall][2] to learn about international professional communication strategies in the multinational group, the FreeDOS Project.
**You started the [FreeDOS project][3] in 1994. How did you communicate with the global network of developers for this project at the beginning? How have your communication strategies for international communication changed over the years?**
We've gone through a few different ways to communicate with each other.
In the early 1990s, USENET was a common way to communicate with a group of people. USENET was very similar to a message forum, but it was globally distributed. Topics were arranged in groups. You could post a message in a USENET group, and someone else would see it and possibly reply to it.
I posted the [first announcement][4] about FreeDOS on the comp.os.msdos.apps group. As we got started on FreeDOS, we used that group to discuss our development work. There are a few benefits of using a group like that:
* It was global, so everyone could participate.
* It was asynchronous, so it didn't matter what timezone you lived in.
* It was open, so everyone could see the conversation.
Around 1996, we moved from USENET to an email list. Email lists were very common at the time, and they remain popular for some uses, such as ours. With an email list, whenever someone sends a message to the list, everyone gets a copy. The downside is that very active email lists can fill up your inbox. But the FreeDOS email lists aren't as active these days as they once were, so our email lists don't tend to have a high bandwidth.
Over the years, folks have experimented with other ways to communicate. Robert Riebisch at BTTR Software set up a general web-based discussion board called ["DOS Ain't Dead"][5] to discuss DOS projects in 1997, and it's still a popular forum for general DOS topics. You can also find FreeDOS topics discussed there. That's not our official discussion board, however; the official place for all FreeDOS development discussions is the [freedos-devel email list][6].
We use freedos-devel to discuss upcoming changes to the FreeDOS distribution, announce new versions of programs, ask for programming help, and generally talk about DOS development.
**What communication issues have you run into while working with a global team? How did you resolve these issues?**
With developers all around the world, in so many languages, from so many cultures, we have had our share of communication issues.
Our de facto language on the email list is English. We never set that as a rule, but almost everyone communicates in English anyway. Sometimes a new subscriber to the email list sends a message in another language, but usually someone who speaks that language can reply to them.
Inevitably, we do have miscommunication issues, usually because of cultural or language problems. For example, someone who doesn't speak English fluently might say something in an awkward way, and someone else might respond negatively to that. But these instances are pretty rare, I think. And we have strong [email list rules][7] that say (among other things) that you need to be nice to each other. And folks police each other pretty well; if there's an issue, it's usually short-lived.
Other issues include culture clash. In international communication, there's a concept of [high-context and low-context][8] communicators. Germany is a typical example of a low-context culture: They get right to the point with very little small talk. Other cultures might see the German style as speaking bluntly, but to a German, that's just a natural way to communicate. On the other hand, Korea or Japan is a typical example of a high-context culture; it would be very unusual for a high-context communicator to talk about a problem in a very direct way.
In the United States, we're more low context than high context, at about the one-quarter mark.
One example of this culture clash is when a user from a high-context country emailed the list to report a bug. I suppose this person viewed a program bug as an embarrassment for the developer, so the person didn't address the bug directly. They didn't provide a specific description of the bug. The other developers on the email list didn't respond well to that. I recall replies along the lines of "What's the problem here?" or "What are you talking about?" All because we communicate differently depending on our background.
**What have been the biggest challenges in creating a DOS for an international audience?**
I'm really glad that we have some very active people in FreeDOS who are working on translating messages in all these programs. There are a few folks who contribute to FreeDOS by translating messages from one language to another and sharing those message files so we can use them in the FreeDOS distribution.
FreeDOS is a small operating system with low memory constraints, so actually our biggest challenge has been technical.
In a more modern system like Linux, you can provide message translation through a service like [catgets][9] or [gettext][10]. Both are programming libraries where the program says, "I need this string [text] in the user's preferred language," and the library gives the program that string. This is an example of internationalization, by providing translations in different languages.
But writing a library like that can take a lot of memory, and a 16-bit operating system like DOS doesn't have a lot of memory to spare. So most early FreeDOS programs didn't bother dealing with it. If the programmer spoke English, they probably wrote their program to use English messages and to accept English input (such as "y" for "yes," and so on).
Unfortunately, that meant someone in Spain or France or Portugal who didn't understand English would have a hard time using FreeDOS. So, I wrote a simplified version of catgets for FreeDOS called Cats. It provided the same catgets function feature set, which meant if you were porting or translating a program from Linux to run on FreeDOS, the catgets function would do the same thing. The programmer wouldn't need to change anything in the source code for the program to work on FreeDOS; they just used FreeDOS Cats.
Catgets looks up a message or string using a _message catalog_ (a file that contains a list of messages in a specific language) and a pair of numbers called the _message set_ and the _message number._ The name catgets comes from the catalog to get a string in the user's preferred language. For example, a message to say "Hello" to the user might be stored in message set 1, as message number 2 in that message set. So you'd have this line in an English catalog file:
`1.2:Hello`
And you'd have other language catalog files that had the same messages translated to other languages. A Spanish catalog might have this line to represent the same message:
`1.2:Hola`
Tom Ehlert modified Cats to be even smaller but also much simpler. This version was named Kitten. Cats and Kitten solved the problem pretty well. A translator could create a message catalog by editing a plain text file, and someone else could use that right away. A lot of FreeDOS programs adopted Cats or Kitten to provide message internationalization. That solved a huge problem for us!
Kitten is not the only solution. Different developers might solve the language problem in different ways. But Kitten is probably the most popular way to do it.
**What are some of the main factors that you consider when communicating interculturally?**
For me, I need to be aware of who I'm talking to when I send a message. If I'm emailing a specific person, I'll use the email they sent me as a guide to guess whether they prefer a high-context or low-context answer. If I don't know, I'll probably default to a lower context mode. That means I'll get to the point quickly, but it's okay to set up some context.
If I'm writing for a more general audience (such as sending emails to our email list, posting an announcement to our website, or whatever), I'll also adopt the lower context communication mode. That's more important on a website, where many readers will probably click off the site if it's too wordy.
**Using your time working on the FreeDOS project as a reference, what advice would you give to someone looking to increase their intercultural communication competence?**
Ever since I learned about high-context vs. low-context communication styles, I've used that as a guide. For anyone who wants to increase their intercultural communication competence, I recommend learning the high- vs. low-context spectrum. Build your own understanding of where different cultures are placed on this spectrum: Italy tends to be around the middle, the UK tends to be around the one-third mark, and so on.
Beyond that, I would recommend always assuming positive intent. If someone reached out to you in an email, read past any preconceptions about how that person communicated and find the message they wanted to convey. A high-context communicator will rarely hit an issue head-on, so you may need to read more carefully. A low-context communicator will probably seem very blunt, but they are just trying to get to the point quickly.
Don't assume based on your own context.
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/10/global-communication-open-source
作者:[Rachel Naegele][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/ranaegele
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/cloud-globe.png?itok=_drXt4Tn (Globe up in the clouds)
[2]: https://opensource.com/users/jim-hall
[3]: https://www.freedos.org/
[4]: https://groups.google.com/g/comp.os.msdos.apps/c/oQmT4ETcSzU/m/O1HR8PE2u-EJ
[5]: https://www.bttr-software.de/forum/board.php
[6]: http://lists.sourceforge.net/lists/listinfo/freedos-user
[7]: http://freedos.sourceforge.net/freedos/lists/remind.txt
[8]: https://en.wikipedia.org/wiki/High-context_and_low-context_cultures
[9]: https://www.ibm.com/docs/en/i/7.3?topic=functions-catgets-retrieve-message-from-message-catalog
[10]: https://www.gnu.org/software/gettext/manual/gettext.html

View File

@@ -1,122 +0,0 @@
[#]: subject: "What is open core?"
[#]: via: "https://opensource.com/article/21/11/open-core-vs-open-source"
[#]: author: "Scott McCarty https://opensource.com/users/fatherlinux"
[#]: collector: "lujun9972"
[#]: translator: " "
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
What is open core?
======
How does open core differ from open source? When is one more useful than
the other?
![A confusing business organization chart][1]
What is open core? Is a project open core, or is a business open core? That's debatable. Like open source, some view it as a [development model][2], others view it as a [business model][3]. As a product manager, I view it more in the context of value creation and value capture.
![market problems based on open core][4]
(Scott McCarty, CC BY-SA 4.0)
With open source, an engineering team can capture more value than it contributes. An engineer participating in an open source project can contribute $1 worth of code, yet get back $10, $20, $30, or more worth of value. This value is measured in both personal brand, as well as ability to lead and influence the project in a direction that is beneficial to their employer.
With open core, at least some of the code is proprietary. With proprietary code, a company hires engineers, solves business problems, and charges for that software. For the proprietary portion of the code base, there is no community-based engineering, so there's no process by which a community member can profit by participating. With proprietary code, a dollar invested in engineering is a dollar returned in code. Unlike open source, a proprietary development process can't return more value than the engineering team contributes (see also: [Why Red Hat is investing in CRI-O and Podman][5]).
This lack of community profit is really important when analyzing open core. There is no community for that part of the code, so there is no community participation, no community profit. If there is no community, there is no potential for a community member to gain the standard benefits of open source (personal brand, influence, right to use, learning, etc.).
There's no differential value created with open core, so in [18 ways to differentiate open source products from upstream suppliers][6], I describe it as a methodology for capturing value. Community-driven open source is about value creation, not value capture. This is a fundamental tension between open source and open core.
### Open core versus glue code
First, let's take a look at what people typically view as open source. As described [on Wikipedia][3], "the open-core model primarily involves offering a 'core' or feature-limited version of a software product as free and open-source software, while offering 'commercial' versions or add-ons as proprietary software." The drawing below shows this model graphically.
An example of this model is SugarCRM, which had a core, open source piece of software as well as a bunch of plugins, many of which were proprietary. Another example of this is [the original plan Microsoft had for the Hot Reload feature in .Net][7] (which has since then been reversed).
![Open Core and Proprietary Diagram][8]
Another related model is what I'll refer to as glue code. Glue code doesn't directly provide a customer business value. Instead, it hangs a bunch of projects together. Notice, in this example, I demonstrate three open source projects, one data-driven [API service][9], and some glue code that holds it all together. Glue code can be open source or proprietary, but this is not what people typically think of when they talk about open core.
An example of open source glue code is Red Hat Satellite Server. It's made up of multiple upstream open source projects like Foreman, Candlepin, Pulp, and Katello, as well as a connection to a data service for updates (as well as [connections with tools like Red Hat Insights][10]). In the case of Satellite server, all of the glue code is open source, but one can easily imagine how other companies might make the choice to employ proprietary code for this functionality.
![An example of open source glue code][11]
### When open core conflicts with community goals
The classic problem with open core is when the upstream community wants to implement a feature that is in one of the proprietary bolt-ons. The company or product which employs the open core model has an incentive to stop this from happening in the open source project on which the proprietary code relies. This creates some serious issues for both the upstream community and for customers.
Potential customers will be incentivized to participate in the community to implement the proprietary features which are perceived as missing. Community members who try to implement these features will be shocked or annoyed when their pull requests are difficult to get accepted or rejected outright.
I've never seen a serious solution for this problem. In this video, [How To Do Open Core Well: 6 Concrete Recommendations][12], Jono Bacon recommends being upfront with community members. He recommends telling them that pull requests which compete with proprietary product features will be rejected. While that's better than not being upfront, it's not a scalable solution. Both the upstream project and the downstream product with proprietary features are constantly changing landscapes. Often, community contributors aren't even paying attention to the downstream product and have no idea which features are implemented downstream, or worse, on the roadmap to be implemented as proprietary features. The upstream community is rarely emotionally engaged with the business problems solved by downstream products, and can easily be confused when their pull requests are rejected.
Even if the community is willing to accept the no-go zones (example: [GitLab Features by Paid Tier][13]), this makes it a high probability that the open source project will be a single-vendor endeavor (example: [GitLab contributions are primarily GitLab employees][14]). It's highly unlikely that competitors will participate, and this will intrinsically limit the value creation of the community. The open core business could still capture value through thought leadership, technology adoption, and customer loyalty, but arguably they will never truly create more code value than they invest.
Apart from these problems, if an upstream project truly adheres to open governance, there's actually nothing the open core business can do to prevent proprietary features from being implemented. Intra-project (within a single project) proprietary code just doesn't work.
### When open core might work
Glue code is a place where open core or proprietary code might work. I'm not advocating for open core, and I often think it's inefficient, but I want to be honest with my analysis. There are indeed natural boundaries between open source projects. Going back to my open source as a supply chain thesis (see also: [The Delicate Art of Product Management with Open Source][15]), a [fuel injector][16] is a fuel injector; it's not an [alternator][17]. These natural demarcation points do make good areas for differentiation of the downstream product from the upstream project (see also: [18 Ways to differentiate open source software products from their upstream projects][6]).
A classic example of proprietary glue code is the original [Red Hat Network (RHN)][18], released in the year 2000. RHN was essentially a SaaS offering which provided updates for [Red Hat Linux][19] machines, and this was before [Red Hat Enterprise Linux][20] was even a thing. For context, when RHN was released, the term open core wasn't even invented yet ([coined in 2008][3]), coincidentally the same year that the [upstream Spacewalk project][21] was released. Back then, everyone was still learning the core competencies of how to do open source well.
In retrospect, I don't think it's a coincidence that RHN existed at the nexus of the natural demarcation point between an upstream Linux distribution and pay-for offering. This naturally fits the mental model of [differentiating a product from the upstream supplier][6]. It might be tempting to conclude - "See!?!? The largest open source company in the world differentiated itself with proprietary code! Open core is the reason Red Hat survived and flourished" - but I'd be careful not to confuse correlation with causation. Red Hat eventually open sourced RHN as Spacewalk and never took a hit to revenue.
Pivoting slightly, one could also make an argument that the cloud providers often follow this model today. It's well known in the industry that most of the large cloud providers carry their own forks of the Linux kernel. These forks have proprietary extensions which make Linux usable in their environments. These features don't solve a customer's business problem directly but instead solve the cloud provider's problems. They're essentially glue code.
Cloud providers have a slightly different motivation for not getting these changes upstream. For them, carrying a fork is often cheaper and/or easier (though not easy) than contributing these features upstream, especially when the changes are often not wanted by the Linux kernel community. Cloud providers are often choosing the best bad idea out of a bunch of bad ideas.
Open core glue code might be called inter-project (between multiple projects) proprietary code. This might work, but arguably, this kind of code is already difficult to implement and doesn't need the perceived "protections" of a proprietary license. Stated another way, open source contributors aren't necessarily incentivized to work on and maintain glue code. It's a natural place where a vendor can differentiate. Often glue code is complex and requires specific integrations between specific versions of upstream projects for specific life cycle requirements. All of these specific requirements make glue code a great place for a product to differentiate itself from the upstream projects without the need for a proprietary license. The velocity (speed and direction) of enterprise integrations are quite different from the velocity needed for collaboration between multiple upstream projects. This velocity mismatch between upstream community needs, and downstream customer needs is a perfect place for differentiation without the need for open core.
### Conclusion
Can open core work? Is it better than open source? Should everyone use it? It seems obvious that Open core can work, but only in very specific situations with very specific types of software (ex. glue code). It seems less obvious that there's any argument that open core is actually better for creating value. Therefore, I do not recommend open core for most businesses. Furthermore, I think the percieved protections that it offers are actually unnecessary.  
Often, vendors find natural places to compete with each other. For example, SUSE runs the [OpenSUSE Build Service][22], which is based on completely open source code. Even though Red Hat could download the source code and set up a competing build service, they haven't. In fact, the upstream Podman project, which is heavily sponsored by Red Hat, uses the [OpenSUSE build service][23]. Though SUSE could easily make this code proprietary, they don't need to. Setting up, running, and maintaining a competing service is a lot of work and doesn't necessarily provide Red Hat customers with a lot of value.
I still think Open Core is a step in the right direction from fully proprietary code (example: [GitLab is open core, GitHub is closed source][24]), but I don't see a compelling reason to promote it as a better alternative to completely open source. In fact, I think it's [exceedingly difficult][12] to do open core well and likely impossible to genuinely create differentiated value with it (see also: [The community-led renaissance of open source][25] and [Fauxpen source is bad for business][26]).
This thesis on open core was developed by working with and learning from hundreds of passionate people in Open Source, including engineers, product managers, marketing managers, sales people, and some of the foremost lawyers in this space. To release new features and capabilities in Red Hat Enterprise Linux and OpenShift, like launching Red Hat Universal Base Image, I've worked closely with so many different teams at Red Hat. I've absorbed 25+ years of institutional knowledge, in my 10+ years here. Now, I'm trying to formalize this a bit in public work like [The Delicate Art of Product Management with Open Source][15] and follow-on articles like this one.
This work has contributed to my recent promotion to Senior Principal Product Manager of [RHEL for Server][27], [arguably the largest open source business in the world][28]. Even with this experience, I'm constantly listening, learning, and seeking truth. I'd love to discuss this subject further in the comments or on Twitter (@fatherlinux).
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/11/open-core-vs-open-source
作者:[Scott McCarty][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/fatherlinux
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/BUSINESS_orgchart1.png?itok=tukiFj89 (A confusing business organization chart)
[2]: https://opensource.org/blog/OpenCore
[3]: https://en.wikipedia.org/wiki/Open-core_model
[4]: https://opensource.com/sites/default/files/values.png
[5]: https://www.redhat.com/en/blog/why-red-hat-investing-cri-o-and-podman
[6]: https://opensource.com/article/21/2/differentiating-products-upstream-suppliers
[7]: https://dusted.codes/can-we-trust-microsoft-with-open-source
[8]: https://opensource.com/sites/default/files/uploads/open_core_diagram1.png (Open Core and Proprietary Diagram)
[9]: https://opensource.com/article/17/8/open-core-vs-open-perimeter
[10]: https://access.redhat.com/documentation/en-us/red_hat_satellite/6.2/html/server_administration_guide/ch06s06
[11]: https://opensource.com/sites/default/files/uploads/open_core_diagram2.png (An example of open source glue code)
[12]: https://www.youtube.com/watch?v=o-OOxOS8oDs
[13]: https://about.gitlab.com/features/by-paid-tier/
[14]: https://gitlab.com/gitlab-org/gitlab-foss/-/graphs/master
[15]: http://crunchtools.com/the-delicate-art-of-product-management/
[16]: https://en.wikipedia.org/wiki/Fuel_injection
[17]: https://en.wikipedia.org/wiki/Alternator
[18]: https://en.wikipedia.org/wiki/Red_Hat_Network
[19]: https://en.wikipedia.org/wiki/Red_Hat_Linux
[20]: https://en.wikipedia.org/wiki/Red_Hat_Enterprise_Linux
[21]: https://spacewalkproject.github.io/
[22]: https://en.opensuse.org/openSUSE:Build_Service_FAQ
[23]: https://build.opensuse.org/package/show/openSUSE:Factory/podman
[24]: https://about.gitlab.com/blog/2016/07/20/gitlab-is-open-core-github-is-closed-source/
[25]: https://opensource.com/article/19/9/community-led-renaissance
[26]: https://opensource.com/article/19/4/fauxpen-source-bad-business
[27]: https://www.redhat.com/en/store/red-hat-enterprise-linux-server
[28]: https://last10k.com/sec-filings/rht/0001087423-19-000012.htm#link_fullReport

View File

@@ -1,109 +0,0 @@
[#]: subject: "5 benefits of switching from Google Analytics to Plausible"
[#]: via: "https://opensource.com/article/22/5/plausible-analytics"
[#]: author: "Tom Greenwood https://opensource.com/users/tpgreenwood"
[#]: collector: "lkxed"
[#]: translator: " "
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
5 benefits of switching from Google Analytics to Plausible
======
Plausible is an open source alternative to Google Analytics.
![The legacy of open source and the tide of progress][1]
Image by: Opensource.com
Google Analytics (GA) has been the industry standard web analytics tool for about as long as there have been analytics tools. Nearly every brief that my WordPress agency receives specifies that GA must be installed. And there is rarely any debate around whether it's the best tool for the job.
My team at Wholegrain Digital has had concerns about GA in terms of privacy, General Data Protection Regulation (GDPR) compliance, performance, user experience, not to mention Google as a global advertising, and search monopoly. However, we continued using GA for 99% of our projects because we didn't feel that there was a strong enough alternative.
Well, that has changed. We've made a decision that GA will no longer be our default analytics tool. Instead, our default analytics tool will be [Plausible][2].
In this article, I'll outline why we consider Plausible a better choice as a default analytics solution, the compromises to be aware of, and how it will impact our clients.
### Why use Plausible instead of Google Analytics
We believe that using Plausible over GA is not a purely ideological choice. There are in fact a number of tangible benefits that make it an objectively better product in many cases. Let's take a look at some of these benefits.
#### Privacy
One of Plausible's headline benefits is that it has been designed as a privacy-first analytics tool. This might sound like an ideological factor, but it has real practical implications too.
Plausible only collects anonymous user data, and does not use cookies. This means that unlike most analytics solutions, it complies with both the GDPR and the European Cookie Law, so it's a tick in the box for legal compliance. It's also hosted in the EU and the data is owned by you so it doesn't get shared with any other organizations, which is another tick.
This has a positive knock-on effect for user experience, because without privacy-invading cookies, you don't need to implement a cookie banner on the website (unless you use cookies for other things). Considering that the first few seconds of a website visit are the most critical to brand experience and conversion rates, cookie banners are arguably the single most damaging thing to the success of any online service. Avoiding these banners puts your brand and message first, helps you make a good first impression, and increases conversion rates.
#### Simpler user interface
The GA dashboard was never a great case study in intuitive design, but as the functionality of GA has expanded, so too has the complexity of the interface. I'm increasingly hearing frustrations from even experienced web marketers that they sometimes struggle to find basic data inside GA.
Plausible has taken the opposite approach and focused on ease of use over quantity of features. The dashboard is beautifully designed to showcase the data you want in a way that is easy to find and understand. It's what most people wish GA to be and it's a breath of fresh air.
![Image of Plausible with a dark theme][3]
Image by: (Tom Greenwood, CC BY-SA 4.0)
This is not just a pleasantry. The reality is that if a tool is easy to use then you will use it, and if it is hard to use then you won't. The simplicity of the Plausible interface means that even though it has less features, many users are likely to get a lot more insights and value from their analytics.
#### Better web performance
The Plausible tracking script is the smallest we are aware of for any analytics service, coming in at less than 1kb compared to 17kb for GA and even more if you're using Google Tag Manager.
Better web performance improves user experience, helps your website to rank better in search engines and improves conversion rates. Web performance matters, and when it comes to web performance, every kilobyte matters.
#### Reduced environmental impact
Plausible's tiny tracking script isn't just good for web performance, it's also good for the environment. At Wholegrain we are world leaders in sustainable web design and understand that every bit of wasted data is also wasted energy and carbon emissions.
This adds up. As a minimum, switching to Plausible would save 16kb per visitor, so for a website with a modest 10K visitors per month this would be 160MB of data per month, or 2GB per year. A back of an envelope calculation using the latest methodology that we have developed for website carbon calculations put this at about the equivalent of 800 grams of CO2. Now multiply that up by the millions of websites running worldwide and you are talking about significant amounts of wasted energy and unnecessary carbon emissions.
But it doesn't stop there. Analytics tools consume energy on the end user's device as they harvest data, in the transmission networks as they send that data back to the data center, and in the data center to store it all for eternity. By tracking less, Plausible is using less energy in its operation than bloated analytics tools such as GA that are tracking many more metrics that most people don't need.
Plausible also hosts the data in data centers with a commitment to using renewable sources of electricity, which is great (though to be fair Google also does that), and they donate 5% of their revenue to good causes, so the money you are paying is also helping support environmental and social projects.
#### More accurate data
Finally, Plausible breaks one of the greatest myths about GA, which is that it is accurate. Plausible's own research and our own experiences with client websites show that GA can significantly under report data, sometimes by as much as 50-60%.
When you look at GA and you think you are looking at all of your website data, you are most likely only looking at a portion of it. This is because GA is more likely to be blocked by ad blockers and privacy friendly web browsers, but perhaps more significantly because GA should not be tracking your visitors unless they have accepted cookies, which many visitors do not.
Plausible therefore offers us a simple way to get a more complete and accurate view of website visitors. Needless to say, if you are a digital marketing manager and you want to make yourself look good, you want to use the analytics service that reports all of your visitors and not just some of them.
### Are there any downsides?
There are very few downsides to using Plausible. If you are a GA power user and genuinely need a lot of its more advanced functionality then Plausible is not going to meet all of your needs. Plausible can track events, conversions, and campaigns but if you need more than that then you'll need another tool.
The only other notable downside to Plausible is that it is not free. There is a monthly fee but it is very reasonable, starting at $6 per month. It's a small price to pay for such a good tool, to protect the privacy of your website visitors and to maintain ownership of your data.
### What are the impacts?
Here at Wholegrain Digital we are implementing Plausible in a way that we hope will offer many of our clients the benefits listed above without the downsides. Nobody will be forced to stop using GA, but we will be talking about the benefits of Plausible proactively with our clients and including it in our proposals as the default option.
In many cases, Plausible is not just capable of meeting a project's requirements, but is objectively a better solution than GA, so we'll be trying to help our clients to reap the benefits of this.
In cases where advanced GA features are required, we will of course stick with GA for now. And in some cases, we may run GA and Plausible in parallel. This has a small overhead in terms of carbon footprint and performance, so it isn't our first choice. However, in some cases it may provide a necessary bridge to help our clients gain confidence in Plausible before making the leap, or help them gain a complete data set while ensuring compliance with privacy laws.
As for the costs, Plausible is a very good value for what it offers, but we will be offering it free of charge to our clients for any websites cared for on our WordPress maintenance service. We hope that this will help lower the barrier to entry and help more of our clients and their website visitors gain the benefits of Plausible.
### It is Plausible!
I hope I've convinced you that Plausible is not just a viable but a really great alternative to GA. If you need any advice on how to figure out the best analytics solution for your website or how to ensure that you are GDPR compliant without compromising user experience, get in touch with me.
*This article originally appeared on the Wholegrain Digital blog and has been republished with permission.*
--------------------------------------------------------------------------------
via: https://opensource.com/article/22/5/plausible-analytics
作者:[Tom Greenwood][a]
选题:[lkxed][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/tpgreenwood
[b]: https://github.com/lkxed
[1]: https://opensource.com/sites/default/files/lead-images/LIFE_wavegraph.png
[2]: https://plausible.io
[3]: https://opensource.com/sites/default/files/2022-05/Plausible-%C2%B7-websitecarbon-com.jpg

View File

@@ -1,120 +0,0 @@
[#]: subject: "SBOM SB Doesnt Stand for Silver Bullet"
[#]: via: "https://www.linux.com/news/sbom-sb-doesnt-stand-for-silver-bullet/"
[#]: author: "Dan Whiting https://www.linuxfoundation.org/blog/sbom-sb-doesnt-stand-for-silver-bullet/"
[#]: collector: "lkxed"
[#]: translator: " "
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
SBOM SB Doesnt Stand for Silver Bullet
======
Software Bill of Materials (SBOMs) are like ingredient labels on food. They are critical to keep consumers safe and healthy, they are somewhat standardized, but it is a lot more exciting to grow or make the food rather than the label.
### What is an SBOM?
What is an SBOM? In short, it is a way to tell another party all of the software that is used in the stack that makes up an application. One benefit of having a SBOM is you know what is in there when a vulnerability comes up. You can easily determine if you are vulnerable and where.
As modern software is built utilizing a base of software already written (no sense in recreating the wheel), it is important that all of the components dont get lost in the shuffle. It isnt readily apparent what a particular piece of software utilizes. So, if a vulnerability for Software A arises, you need to know, do I have that piece of software somewhere in my ecosystem, and, if so, where. Then you can remediate if you need to.
I cant take credit for the food label analogy used in my introduction. I heard it from [Allan Friedman][1], a Senior Advisor and Strategist at the [U.S. Cybersecurity and Infrastructure Security Agency][2] (CISA) and a key SBOM advocate, when he presented about SBOMs at the RSA Conference 2022 with [Kate Stewart][3], the VP of Dependable Embedded Systems here at the Linux Foundation. Allan made the point that food labels only provide information. The consumer needs to read and understand them and take appropriate action. For instance, if they are allergic to peanuts, they can look at an ingredient label and determine if they can safely eat the food.
SBOMs are similar they tell a person what software is used as an “ingredient” so someone can determine if they need to take action if a vulnerability arises. It isnt a silver bullet, but it is a vital tool. Without SBOMs no one can track what component “ingredients” are in their software applications.
### SBOMs and the Software Supply Chain
Supply chains are impacting our lives more than just restricting availability of consumer goods. Software supply chains are immensely more complicated now as software is built with pre-existing components. This makes software better, more effective, more powerful, etc. But it also introduces risk as more and more parties touch a particular piece of software. Much like our world has become so interdependent, so has our software.
Understanding what is in the supply chain for our software helps us effectively secure it. When a new risk emerges, we know what we need to do.
### SBOMs and Software Security
SBOMs are increasingly being recognized as an important pillar in any comprehensive software security plan. A global [survey conducted in 2021 Q3 by the Linux Foundation][4] found that 78% of organizations responding plan to use SBOMs in 2022. Additionally, the recently published [Open Source Software Security Mobilization Plan][5] recommends SBOMs be universal and the [U.S. Executive Order on Improving the Nations Cybersecurity][6] requires SBOMs be provided for software purchased by the U.S. government. And, as Allan points out in his talk, “We buy everything.” The E.O. actually lays out a nice summary of SBOMs and their benefits:
The term “Software Bill of Materials” or “SBOM” means a formal record containing the details and supply chain relationships of various components used in building software. Software developers and vendors often create products by assembling existing open source and commercial software components. The SBOM enumerates these components in a product. It is analogous to a list of ingredients on food packaging. An SBOM is useful to those who develop or manufacture software, those who select or purchase software, and those who operate software. Developers often use available open source and third-party software components to create a product; an SBOM allows the builder to make sure those components are up to date and to respond quickly to new vulnerabilities. Buyers can use an SBOM to perform vulnerability or license analysis, both of which can be used to evaluate risk in a product. Those who operate software can use SBOMs to quickly and easily determine whether they are at potential risk of a newly discovered vulnerability. A widely used, machine-readable SBOM format allows for greater benefits through automation and tool integration. The SBOMs gain greater value when collectively stored in a repository that can be easily queried by other applications and systems. Understanding the supply chain of software, obtaining an SBOM, and using it to analyze known vulnerabilities are crucial in managing risk.
Allan and Kate spent time in their talk going into the current state of SBOMs, challenges, benefits, tools available for creating and sharing SBOMs, what is a minimum SBOM, standards being developed, making them fully automated, and more. Look for some future LF Blog posts digging into these.
But there are things you can do now.
### What can you and your organization do now?
Allan and Kate laid out several things you and your organization can do, starting now. Starting within your organization:
Next week: Understand origins of software your organization is using
* Commercial: can you ask for an SBOM?
* Open source: do you have an SBOM for the binary or sources youre importing?
Three months: Understand what SBOMs your customers will require
Expectations: which standards, dependency depth, licensing info?
Six months: Prototype and deploy
Implement SBOM through using an OSS tool and/or starting a conversation with vendor
And participate in ongoing discussions to determine best practices for the ecosystem and contribute to open source project any code developed to support SBOMs.
### But there are also steps you can take as an individual: 
Next week: Start playing with an open source SBOM tool and apply it to a repo
Three months: Have an SBOM strategy that explicitly identifies tooling needs
Six months:
Begin SBOM implementation through using an OSS tool or starting a conversation with vendor
Participate in a plugfest and try to consume anothers SBOM
And make sure to share any open source and commercial tools you find helpful and work with the tools to help harden them, test and report bugs, and push them to scale.
### How can you shape the future of SBOMs?
First, I want to highlight some upcoming opportunities they shared to help shape the future of SBOMs. CISA is running public Tooling & Implementation work stream discussions in July 2022. They are the same, but occur at different times to help accommodate more time zones:
* July 13, 2022 3:00-4:30 PM ET
* July 21, 2022 9:30-11:00 AM ET
If you want to participate, please email [SBOM@cisa.dhs.gov][7].
Additionally, there will be “[plugfests][8]” to be announced soon, and they suggested organizations already adopting SBOMs publish case studies and reference tooling workflows to help others.
### Conclusion
SBOMs are here to stay. If you arent already, get on the train now. It is pulling out of the station, but you still have an opportunity to help shape where it is going and how well the journey goes.
Allans and Kates slides are available [here][9]. If you registered to attend the RSA Conference, you can now watch their full presentation on demand [here][10].
### The Software Package Data ExchangeⓇ (SPDXⓇ)
The Linux Foundation hosts SPDX, which is an open standard for communicating software bill of material information, including components, licenses, copyrights, and security references. SPDX reduces redundant work by providing a common format for companies and communities to share important data, thereby streamlining and improving compliance. The SPDX specification is an international open standard (ISO/IEC 5962:2021). Learn more at [spdx.dev][11].
The post [SBOM SB Doesnt Stand for Silver Bullet][12] appeared first on [Linux Foundation][13].
--------------------------------------------------------------------------------
via: https://www.linux.com/news/sbom-sb-doesnt-stand-for-silver-bullet/
作者:[Dan Whiting][a]
选题:[lkxed][b]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://www.linuxfoundation.org/blog/sbom-sb-doesnt-stand-for-silver-bullet/
[b]: https://github.com/lkxed
[1]: https://www.linkedin.com/in/allanafriedman/
[2]: https://www.cisa.gov/
[3]: https://www.linkedin.com/in/katestewartaustin/
[4]: https://www.linuxfoundation.org/tools/the-state-of-software-bill-of-materials-sbom-and-cybersecurity-readiness/
[5]: https://openssf.org/oss-security-mobilization-plan/
[6]: https://openssf.org/blog/2021/05/14/how-lf-communities-enable-security-measures-required-by-the-us-executive-order-on-cybersecurity/
[7]: https://www.linux.com/mailto:SBOM@cisa.dhs.gov
[8]: https://en.wikipedia.org/wiki/Plugtest
[9]: https://www.linuxfoundation.org/wp-content/uploads/Tooling-up-Getting-SBOMs-to-Scale_slides.pdf
[10]: https://www.rsaconference.com/usa/agenda/session/Tooling%20up%20Getting%20SBOMs%20to%20Scale
[11]: https://spdx.dev/
[12]: https://www.linuxfoundation.org/blog/sbom-sb-doesnt-stand-for-silver-bullet/
[13]: https://www.linuxfoundation.org/

View File

@@ -1,63 +0,0 @@
[#]: subject: "Accessibility in Fedora Workstation"
[#]: via: "https://fedoramagazine.org/accessibility-in-fedora-workstation/"
[#]: author: "Christian Fredrik Schaller https://fedoramagazine.org/author/uraeus/"
[#]: collector: "lkxed"
[#]: translator: " "
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
Accessibility in Fedora Workstation
======
![Accessibility in Fedora Workstation Featured Image][1]
Photo by [Elizabeth Woolner][2] on [Unsplash][3]
The first concerted effort to support accessibility under Linux was undertaken by Sun Microsystems when they decided to use GNOME for Solaris. Sun put together a team focused on building the pieces to make GNOME 2 fully accessible and worked with hardware makers to make sure things like Braille devices worked well. I even heard claims that GNOME and Linux had the best accessibility of any operating system for a while due to this effort. As Sun started struggling and got acquired by Oracle this accessibility effort eventually trailed off with the community trying to pick up the slack afterwards. Especially engineers from Igalia were quite active for a while trying to keep the accessibility support working well.
But over the years we definitely lost a bit of focus on this and we know that various parts of GNOME 3 for instance arent great in terms of accessibility. So at Red Hat we have had a lot of focus over the last few years trying to ensure we are mindful about diversity and inclusion when hiring, trying to ensure that we dont accidentally pre-select against underrepresented groups based on for instance gender or ethnicity. But one area we realized we hadnt given so much focus recently was around technologies that allowed people with various disabilities to make use of our software. Thus I am very happy to announce that Red Hat has just hired Lukas Tyrychtr, who is a blind software engineer, to lead our effort in making sure Red Hat Enterprise Linux and Fedora Workstation has excellent accessibility support!
Anyone who has ever worked for a large company knows that getting funding for new initiatives is often hard and can take a lot of time, but I want to highlight how I was extremely positively surprised at how quick and easy it was to get support for hiring Lukas to work on accessibility. When Jiri Eischmann and I sent the request to my manager, Stef Walter, he agreed to champion the same day, and when we then sent it up to Mike McGrath who is the Vice President of Linux Engineering he immediately responded that he would bring this to Tim Cramer who is our Senior Vice President of Software Engineering. Within a few days we had the go ahead to hire Lukas. The fact that everyone just instantly agreed that accessibility is important and something we as a company should do made me incredibly proud to be a Red Hatter.
What we hope to get from this is not only a better experience for our users, but also to allow even more talented engineers like Lukas to work on Linux and open source software at Red Hat. I thought it would be a good idea here to do a quick interview with Lukas Tyrychtr about the state of accessibility under Linux and what his focus will be.
Christian: Hi Lukas, first of all welcome as a full time engineer to the team! Can you tell us a little about yourself?
Lukas: Hi, Christian. For sure. I am a completely blind person who can see some light, but thats basically it. I started to be interested in computers around 2009 or so, around my 15th or 16th birthday. First, because of circumstances, I started tinkering with Windows, but Linux came shortly after, mainly because of some pretty good friends. Then, after four years the university came and the Linux knowledge paid off, because going through all the theoretical and practical Linux courses there was pretty straightforward (yes, there was no GUI involved, so it was pretty okay, including some custom kernel configuration tinkering). During that time, I was contacted by Red Hat associates whether Id be willing to help with some accessibility related presentation at our faculty, and thats how the collaboration began. And, yes, the hire is its current end, but thats actually, I hope, only the beginning of a long and productive journey.
Christian: So as a blind person you have first hand experience with the state of accessibility support under Linux. What can you tell us about what works and what doesnt work?
Lukas: Generally, things are in pretty good shape. Braille support on text-only consoles basically just always works (except for some SELinux related issues which cropped up). Having speech there is somewhat more challenging, the needed kernel module ([Speakup][4] for the curious among the readers) is not included by all distributions, unfortunately it is not included by Fedora, for example, but Arch Linux has it. When we look at the desktop state of affairs, there is basically only a single screen reader (an application which reads the screen content), called [Orca][5], which might not be the best position in terms of competition, but on the other hand, stealing Orca developers would not be good either. Generally, the desktop is usable, at least with GTK, Qt and major web browsers and all recent Electron based applications. Yes, accessibility support receives much less testing than I would like, so for example, a segmentation fault with a running screen reader can still unfortunately slip through a GTK release. But, generally, the foundation works well enough. Having more and naturally sounding voices for speech synthesis might help attract more blind users, but convincing all the players is no easy work. And then theres the issue of developer awareness. Yes, everything is in some guidelines like the GNOME ones, however I saw much more often than Id like to for example a button without any accessibility labels, so Id like to help all the developers to fix their apps so accessibility regressions dont get to the users, but this will have to improve slowly, I guess.
Christian: So you mention Orca, are there other applications being widely used providing accessibility?
Lukas: Honestly, only a few. Theres Speakup a kernel module which can read text consoles using speech synthesis, e.g. a screen reader for these, however without something like Espeakup (an Espeak to Speakup bridge) the thing is basically useless, as it by default supports hardware synthesizers, however this piece of hardware is basically a think of the past, e.g. I have never seen one myself. Then, theres [BRLTTY][6]. This piece of software provides braille output for screen consoles and an API for applications which want to output braille, so the drivers can be implemented only once. And thats basically it, except for some efforts to create an Orca alternative in Rust, but thats a really long way off. Of course, utilities for other accessibility needs exist as well, but I dont know much about these.
Christian: What is your current focus for things you want to work on both yourself and with the larger team to address?
Lukas: For now, my focus is to go through the applications which were ported to GTK 4 as a part of the GNOME development cycle and ensure that they work well. It includes adding a lot of missing labels, but in some cases, it will involve bigger changes, for example, GNOME Calendar seems to need much more work. During all that, educating developers should not be forgotten either. With these things out of the way, making sure that no regressions slip to the applications should be addressed by extending the quality assurance and automated continuous integration checks, but thats a more distant goal.
Christian: Thank you so much for talking with us Lukas, if there are other people interested in helping out with accessibility in Fedora Workstation what is the best place to reach you?
Actually for now the easiest way to reach me is by email at [ltyrycht@redhat.com][7]. Be happy to talk to anyone wanting to help with making Workstation great for accessibility.
--------------------------------------------------------------------------------
via: https://fedoramagazine.org/accessibility-in-fedora-workstation/
作者:[Christian Fredrik Schaller][a]
选题:[lkxed][b]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://fedoramagazine.org/author/uraeus/
[b]: https://github.com/lkxed
[1]: https://fedoramagazine.org/wp-content/uploads/2022/06/Accessibility-in-Fedora-Workstation-816x345.jpg
[2]: https://unsplash.com/@elizabeth_woolner?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText
[3]: https://unsplash.com/s/photos/accessibility?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText
[4]: http://www.linux-speakup.org/speakup.html
[5]: https://wiki.gnome.org/action/show/Projects/Orca?action=show&redirect=Orca
[6]: https://brltty.app/
[7]: https://fedoramagazine.org/mailto:ltyrycht@redhat.com

View File

@@ -1,121 +0,0 @@
[#]: subject: "My honest review of the HP Dev One"
[#]: via: "https://opensource.com/article/22/7/hp-dev-one-review"
[#]: author: "Anderson Silva https://opensource.com/users/ansilva"
[#]: collector: "lkxed"
[#]: translator: " "
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
My honest review of the HP Dev One
======
Here are my first impressions of the hardware, running the pre-installed Pop!_OS, and running Fedora on HP's new Linux-based laptop.
![Working from home at a laptop][1]
Image by:
Opensource.com
A few weeks ago, HP joined the bandwagon of major laptop manufacturers releasing a Linux-based laptop, the [HP Dev One][2]. The brand joins others such as Lenovo and Dell, offering a laptop with a pre-installed distribution of Linux in the US market. HP joined forces with smaller Linux-based laptop brand System76 to pre-install Pop!_OS as their distribution of choice on the device. Pop!_OS is a Ubuntu-based distribution, which System76 started (and is currently the primary maintainer) to maximize the features of its own laptops sold on its website.
This article is a quick look at the HP Dev One, including first impressions of the hardware itself and running the pre-installed Pop!_OS and then Fedora on it after a few days. It is not about comparing them, just a few notes on how well they did on the HP Dev One.
### HP Dev One hardware
I havent owned an HP laptop in over a decade. I dont even remember why I distanced myself from the brand, but somehow it just happened. So, when I read about the HP Dev One, several things sparked my interest. Heres a list of them. Some may be silly or nit-picking, but they still carried some weight in my decision:
* The most obvious reason was it came with Linux and not Windows.
* I have never used Pop!_OS, so the fact that HP chose Pop!_OS made me curious to use it.
* I have never owned an AMD-based laptop. The HP Dev One comes with an AMD RYZEN™ 7 PRO 5850U Processor with eight cores and 16 threads.
* The specs versus price seemed good. The price is $1099 USD, which is very reasonable compared to other brands with similar specs.
* No Windows key on the keyboard. Instead, it says “super,” which I think is cool.
* Upgradeable RAM. The laptop comes with 16 GB of RAM, but unlike so many laptops nowadays, it is not soldered on the board, so you can upgrade it (more on upgrading below).
* The laptop was in stock with a commitment for fast shipping.
* Reviews were favorable.
For all of the reasons above, I ordered it, and two days later, I had the HP Dev One on my doorstep.
![HP Dev One super key][3]
Image by:
(Anderson Silva, CC BY-SA 4.0)
By the time the laptop arrived, the extra 64 GB of RAM I had ordered had also arrived, so the first thing I wanted to do was upgrade the RAM. It turned out that the bottom plate of the HP Dev One has very small, special (yet not proprietary) screws, so I had to run to the hardware store to get the proper screwdriver.
![HP Dev One RAM upgrade][4]
Image by:
(Anderson Silva, CC BY-SA 4.0)
I agree with [other online reviews][5] regarding the quality of the laptop. It does feel sturdy. The trackpad feel is good enough, and I had no issue with it. I found the keyboard not to be as good as some other reviewers claim. To me, the keys are a little heavy, and they feel almost a bit like silicone or rubber. I didn't find it terribly comfortable. In fact, I am typing this article in the HP Dev One, and I almost feel like I need to take a break here and there to let my fingertips rest.
The 1080p screen is bright, but also very reflective. If you are a Thinkpad trackpoint fan, you will definitely enjoy this feature on the HP Dev One. The backlit keyboard is nice, and the built-in camera cover is something more laptops should adopt.
![HP Dev One top view][6]
Image by:
(Anderson Silva, CC BY-SA 4.0)
One question or possible issue I have with the HP Dev One is the fact that their website talks about the one-year customer service and warranty on the machine, but I havent been able to find a way to extend that warranty or even upgrade to something more premium like an onsite or next day part replacement in case I were ever to need it.
### Pop!_OS on HP Dev One
As previously mentioned, Ive never used Pop!_OS. Ive used Ubuntu and many other distributions, but to me, Pop!_OS was a relatively familiar yet new experience. Here are a few notes:
#### The good
* Coming from a Fedora and mostly vanilla GNOME background, the four-finger gesture in Pop!_OS took a little getting used to, but once I got into it, it made navigating their implementation of GNOME borderline fun.
* The Pop!_OSs software shop is called Pop!_Shop. It contains a great variety of software without any need to enable special repositories. It is easy to use, and installation is fast.
* The integration between Pop!_OS and the hardware really is well done. Congratulations to both System76 and HP engineers for putting this machine together.
* Pop!_OS has a nice built-in feature for backup and restoring your installation w/o destroying your home directory.
* I installed Steam and a few games, and it worked pretty well.
* I ran a couple of test containers with podman, and it worked very nicely as well.
* I installed a virtual machine, and it ran very smoothly, too.
#### The not so good
* The default wallpaper that comes with the HP Dev One looks a bit fuzzy to me. For such a nice machine, it feels like the wallpaper is running at the wrong resolution. To be fair, there are other wallpapers to choose from in the Settings.
* The out-of-the-box fonts for Pop!_OS could be better. I find them hard to read, and in my opinion, it makes the UI too crammed.
* Adding the USB-C powered 4K monitor worked OK, but my eyes noticed slight flickering in some parts of the screen. Could this be an X11 issue, given that Pop!_OS defaults to X11?
### Fedora on HP Dev One
I played around with Pop!_OS for about two days before deciding to boot into Fedora using a live USB media. I did that first to see what type of hardware detection Fedora could do out of the box. To my surprise, everything worked right away. Thats when I decided to wipe the entire 1 TB SSD and install Fedora on the HP Dev One. As promised, this is not a Fedora vs. Pop!_OS comparison article; it is merely a few notes on both distributions running on this Linux-focused hardware.
In case you havent read my bio in this article, and for the sake of transparency, I am a Fedora contributor, so it is fair for me to say that I am biased towards the Fedora distribution, but dont let that make you think I recommend Fedora over Pop!_OS on the HP Dev One. They are both great distributions, and they both run very nicely on it. Take your pick!
I can tell you that Fedora runs smoothly on the HP Dev One, and although there may be some performance tuning to match some of the benchmark numbers against Pop!_OS, I have been very pleased with its performance. Using the three-finger gestures to move between virtual desktops is a lot more natural to me than the four-finger ones in Pop!_OS, and Ive been able to run Steam and Proton-based games on Fedora just like Pop!_OS.
The only comparison I will make is that when using the secondary USB-C 4K monitor with Fedora, I did not experience any flickering. Was it because of Wayland?
### Final thoughts
Ive had the HP Dev One for a little over four days now, and Ive run Pop!_OS and Fedora on it so far. I even restored Pop!_OS after a full Fedora installation, which was a very easy process. Somehow, Pop!_OS detected it was an HP Dev One and did all the needed installation, including the HP-based wallpapers, without me having to do any extra steps.
As I finished this article, yet again, I went back to Fedora (force of habit), but I wouldnt have any issue staying on Pop!_OS on the HP Dev One. Who knows, maybe I might even try different distributions in the future.
At the end of the day, the HP Dev One is a solid Linux laptop without a Windows key and no AMD, Intel, or Windows stickers on it. It is fast, feels well built, and is reasonably priced especially given how quickly it ships to you (US only). I would love to see HP provide more documentation on their website about extending the warranty, and I hope they will be able to make this laptop available in other parts of the world.
--------------------------------------------------------------------------------
via: https://opensource.com/article/22/7/hp-dev-one-review
作者:[Anderson Silva][a]
选题:[lkxed][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/ansilva
[b]: https://github.com/lkxed
[1]: https://opensource.com/sites/default/files/lead-images/wfh_work_home_laptop_work.png
[2]: https://hpdevone.com/
[3]: https://opensource.com/sites/default/files/2022-07/superkey.jpg
[4]: https://opensource.com/sites/default/files/2022-07/ram.jpg
[5]: https://www.techrepublic.com/article/system76-hp-perfect-dev-one/
[6]: https://opensource.com/sites/default/files/2022-07/topview.jpg

View File

@@ -1,80 +0,0 @@
[#]: subject: "What's new with Awk?"
[#]: via: "https://opensource.com/article/22/10/whats-new-awk"
[#]: author: "Jim Hall https://opensource.com/users/jim-hall"
[#]: collector: "lkxed"
[#]: translator: " "
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
What's new with Awk?
======
Brian Kernighan discusses the scripting tool Awk, from its creation to current work on Unicode support.
Awk is a [powerful scripting tool][4] that makes it easy to process text. Awk scripts use a pattern-action syntax, where Awk performs an action for every line in a file that matches a pattern. This provides a flexible yet powerful scripting language to deal with text. For example, the one-line Awk script `/error/ {print $1, $2, $3}` will print the first three space-delimited fields for any line that contains the word `error`.
While we also have the GNU variant of Awk, called Gawk, the original Awk remains under development. Recently, Brian Kernighan started a project to add Unicode support to Awk. I met with Brian to ask about the origins of Awk and his recent development work on Awk.
Jim Hall: Awk is a great tool to parse and process text. How did it start?
Brian Kernighan: The most direct influence was a tool that Marc Rochkind developed while working on the Programmer's Workbench system at Bell Labs. As I remember it now, Marc's program took a list of regular expressions and created a C program that would read an input file. Whenever the program found a match for one of the regular expressions, it printed the matching line. It was designed for creating error checking to run over log files from telephone operations data. It was such a neat idea—Awk is just a generalization.
Jim: AWK stands for the three of you who created it: Al Aho, Peter Weinberger, and Brian Kernighan. How did the three of you design and create Awk?
Brian: Al was interested in regular expressions and had recently implemented egrep, which provided a very efficient lazy-evaluation technique for a much bigger class of regular expressions than what grep provided. That gave us a syntax and working code.
Peter had been interested in databases, and as part of that he had some interest in report generation, like the RPG language that IBM provided. And I had been trying to figure out some kind of editing system that made it possible to handle strings and numbers with more or less equal ease.
We explored designs, but not for a long time. I think Al may have provided the basic pattern-action paradigm, but that was implicit in a variety of existing tools, like grep, the stream editor sed, and in the language tools YACC and Lex that we used for implementation. Naturally, the action language had to be C-like.
Jim: How was Awk first used at Bell Labs? When was Awk first adopted into Unix?
Brian: Awk was created in 1977, so it was part of 7th-edition Unix, which I think appeared in about 1979. I wouldn't say it was adopted, so much as it was just another program included because it was there. People picked it up very quickly, and we soon had users all over the Labs. People wrote much bigger programs than we had ever anticipated, too, even tens of thousands of lines, which was amazing. But for some kinds of applications, the language was a good match.
Jim: Has Awk changed over the years, or is Awk today more or less the same Awk from 1977?
Brian: Overall, it's been pretty stable, but there have been a fair number of small things, mostly to keep up with at least the core parts of Gawk. Examples include things like functions to do case conversion, shorthands for some kinds of regular expressions, or special filenames like `/dev/stderr`. Internally, there's been a lot of work to replace fixed-size arrays with arrays that grow. Arnold Robbins, who maintains Gawk, has also been incredibly helpful with Awk, providing good advice, testing, code, and help with Git.
Jim: You're currently adding Unicode support to Awk. This is one of those projects that seems obvious when you hear it, because Unicode is everywhere, but not every program supports it yet. Tell us about your project to add Unicode to Awk.
Brian: It's been sort of embarrassing for a while now that Awk only handled 8-bit input, though in fairness it predates Unicode by 10 or 20 years. Gawk, the GNU version, has handled Unicode properly for quite a while, so it's good to be up to date and compatible.
Jim: How big of a project is adding Unicode support? Did this require many changes to the source code?
Brian: I haven't counted, but it's probably 200 or 300 lines, primarily concentrated in either the regular expression recognizer or in the various built-in functions that have to operate in characters, not bytes, for Unicode input.
Jim: How far along are you in adding Unicode to Awk?
Brian: There's a branch of the code at GitHub that's pretty up to date. It's been tested, but there's always room for more testing.
One thing to mention: It handles UTF-8 input and output, but for Unicode code points, which are not the same thing as Unicode graphemes. This distinction is important but technically very complicated, at least as I understand it. As a simple example, a letter with an accent could be represented as two code points (letter and accent) or as a single character (grapheme). Doing this right, whatever that means, is very hard.
Jim: In a Computerphile video, you mention adding support for comma-separated values (CSV) parsing to Awk. How is that project going?
Brian: While I had my hands in the code again, I did add support for CSV input, since that's another bit of the language that was always clunky. I haven't done anything for CSV output, since that's easy to do with a couple of short functions, but maybe that should be revisited.
Jim: What kinds of things do you use Awk for in your day-to-day work?
Brian: Everything. Pretty much anything that fiddles text is a target for Awk. Certainly, the Awk program I use most is a simple one to make all lines in a text document the same length. I probably used it 100 times while writing answers to your questions.
Jim: What's the coolest (or most unusual) thing you have used Awk to do?
Brian: A long time ago, I wrote a C++ program that converted Awk programs into C++ that looked as close to Awk as I could manage, by doing things like overloading brackets for associative arrays. It was never used, but it was a fun exercise.
--------------------------------------------------------------------------------
via: https://opensource.com/article/22/10/whats-new-awk
作者:[Jim Hall][a]
选题:[lkxed][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/jim-hall
[b]: https://github.com/lkxed
[1]: https://opensource.com/sites/default/files/lead-images/coffee_tea_laptop_computer_work_desk.png
[2]: https://unsplash.com/@jonasleupe?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText
[3]: https://unsplash.com/s/photos/tea-cup-computer?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText
[4]: https://opensource.com/resources/what-awk

View File

@@ -1,263 +0,0 @@
[#]: subject: "Solve a charity's problem with the Julia programming language"
[#]: via: "https://opensource.com/article/21/1/solve-problem-julia"
[#]: author: "Chris Hermansen https://opensource.com/users/clhermansen"
[#]: collector: "lkxed"
[#]: translator: " "
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
Solve a charity's problem with the Julia programming language
======
See how Julia differs from Java, Python, and Groovy to solve a food bank's real-world problem.
![Puzzle pieces coming together to form a computer screen][1]
Image by: Opensource.com
I have been writing a series of articles about solving a nice, small, and somewhat unusual problem in different programming languages ([Groovy][2], [Python][3], and [Java][4] so far).
Briefly, the problem is how to unpack bulk supplies into their units (for example, dividing a 10 pack of one-pound bags of your favorite coffee) and repackage them into hampers of similar value to distribute to struggling neighbors in the community.
The three solutions I have already explored constructed lists of the number of bulk packages acquired. I accomplished this by using maps in Groovy, dictionaries in Python, and tuples implemented as utility classes in Java. I used list-processing functionality in each language to unpack the bulk packages into a list of their constituents, which I modeled using maps, dictionaries, and tuples, respectively. I needed to take an iterative approach to move units from a list into hampers; this iterative approach was quite similar from one language to the other, with the minor difference that I could use `for {...}` loops in Groovy and Java and needed `while…:` in Python. But all in all, they used very similar solutions with hints of functional programming and behavior encapsulated in objects here and there.
### Meet Julia
In this article, I'll explore the same problem in [Julia][5], which (among other things) means leaving aside the object-oriented and functional programming paradigms I'm used to. I struggle with languages that aren't object-oriented. I've been programming in Java since around 1997 and in Groovy since about 2008, so I'm used to having data and behavior bundled together. Aside from just generally liking the look of code where method calls hang off objects or sometimes classes, I really like the way class documentation packages up what data is handled by the class and how it is handled. This seems so "natural" to me now that learning a language whose documentation describes types and functions separately seems difficult to me.
And speaking of learning a language, I'm a real neophyte when it comes to Julia. I like its orientation toward the kinds of problems I typically need to solve (e.g., data, computations, results). I like the desire for speed. I like the decision to make Julia a language in which complicated problems can be solved using a modular and iterative approach. I like the idea of making great existing analytical libraries available. But, my jury is still out on the non-object-oriented design. I also seem to use functional approaches in my Groovy and Java programming more often, so I think I might miss this in Julia.
But enough speculation, let's code something!
### The Julia solution
My first decision is how to implement the data model. Julia supports *composite types*, seemingly similar to `struct` in C, and Julia even uses the keyword `struct`. Of note is that a `struct` is immutable (unless declared a `mutable struct` ), which is fine for this problem since the data doesn't need to be mutated.
By following the approach I took in the Java solution, the `Unit struct` can be defined as:
```
struct Unit
       item::String
       brand::String
       price::Int
end
```
Similarly, `Pack` is defined as the bulk package of `Unit` instances:
```
struct Pack
      unit::Unit
      count::Int
      Pack(item, brand, unitCount,p ackPrice) =
            new(Unit(item, brand, div(packPrice,unitCount)), unitCount)
end
```
There is an interesting thing here: a Julia "inner constructor." In the Java solution, I decided that the units inside bulk packages are (in my mind, anyway) a part of the bulk package and not something seen externally, so I decided I wanted to pass in the item, brand, number of units, and package price and have the `Pack` object create its unit internally. I'll do the same thing here.
Because Julia isn't object-oriented, I can't add methods to `Pack` to give unit price vs. pack price or to unpack it into a list of `Unit` instances. I can declare "getter" functions that accomplish the same tasks. (I probably don't need these, but I'll do it anyway to see how Julia methods work):
```
item(pack::Pack) = pack.unit.item
brand(pack::Pack) = pack.unit.brand
unitPrice(pack::Pack) = pack.unit.price
unitCount(pack::Pack) = pack.count
packPrice(pack::Pack) = pack.unit.price * pack.count
unpack(pack::Pack) = Iterators.collect(Iterators.repeated(pack.unit,pack.count))
```
The `unpack()` method is quite similar to the method of the same name I declared in the Java class `Pack`. The function `Iterators.repeated(thing,N)` creates an iterator that will deliver `N` copies of `thing`. The `Iterators.collect` (`iterator` ) function processes the `iterator` to yield an array made up of the elements it delivers.
Finally, the `Bought struct` :
```
struct Bought
      pack::Pack
      count::Int
end
unpack(bought::Bought) =        
     Iterators.collect(Iterators.flatten(Iterators.repeated(unpack(bought.pack),
         bought.count)))
```
Once again, I'm creating an array of an array of unpacked `Pack` instances (i.e., units) and using `Iterators.flatten()` to turn that into a simple array.
Now I can construct the list of what I bought:
```
packs = [
        Bought(Pack("Rice","Best Family",10,5650),1),
        Bought(Pack("Spaghetti","Best Family",1,327),10),
        Bought(Pack("Sardines","Fresh Caught",3,2727),3),
        Bought(Pack("Chickpeas","Southern Style",2,2600),5),
        Bought(Pack("Lentils","Southern Style",2,2378),5),
        Bought(Pack("Vegetable oil","Crafco",12,10020),1),
        Bought(Pack("UHT milk","Atlantic",6,4560),2),
        Bought(Pack("Flour","Neighbor Mills",10,5200),1),
        Bought(Pack("Tomato sauce","Best Family",1,190),10),
        Bought(Pack("Sugar","Good Price",1,565),10),
        Bought(Pack("Tea","Superior",5,2720),2),
        Bought(Pack("Coffee","Colombia Select",2,4180),5),
        Bought(Pack("Tofu","Gourmet Choice",1,1580),10),
        Bought(Pack("Bleach","Blanchite",5,3550),2),
        Bought(Pack("Soap","Sunny Day",6,1794),2)]
```
I'm starting to see a pattern here… this looks surprisingly like the Java solution to this problem. As then, this shows that I bought one pack of Best Family Rice containing 10 units that cost 5650 (using those crazy monetary units, like in the other examples). I bought one bulk pack of 10 bags of rice, and I bought 10 bulk packs of one bag each of spaghetti.
With the list packs of what I bought, I can now unpack into the units before working on redistributing them:
```
units = Iterators.collect(Iterators.flatten(unpack.(packs)))
```
What's going on here? Well, a construct like `unpack.(packs)` —that is, the dot between the function name and the argument list—applies the function `unpack()` to each element in the list `packs`. This will generate a list of lists corresponding to the unpacked groups of `Packs` I bought. To turn that into a flat list of units, I apply `Iterators.flatten()`. Because `Iterators.flatten()` is lazy, to make the flatten thing happen, I wrap it in `Iterators.collect()`. This kind of composition of functions adheres to the spirit of functional programming, even though you don't see the functions chained together, as programmers who write functionally in JavaScript, Java, or what-have-you are familiar with.
One observation is that the list of units created here is actually an array whose starting index is 1, not 0.
With units being the list of units purchased and unpacked, I can now take on repacking them into hampers.
Here's the code, which is not exceptionally different than the versions in Groovy, Python, and Java:
```
 1      valueIdeal = 5000
 2      valueMax = round(valueIdeal * 1.1)
 3      hamperNumber = 0
       
 4      while length(units) > 0
 5          global hamperNumber += 1
 6          hamper = Unit[]
 7          value = 0
 8          canAdd = true
 9          while canAdd
10              u = rand(0:(length(units)-1))
11              canAdd = false
12              for o = 0:(length(units)-1)
13                  uo = (u + o) % length(units) + 1
14                  unit = units[uo]
15                  if length(units) < 3 || findfirst(u -> u == unit,hamper) === nothing && (value + unit.price) < valueMax
16                      push!(hamper,unit)
17                      value += unit.price
18                      deleteat!(units,uo)
19                      canAdd = length(units) > 0
20                      break
21                  end
22              end
23          end
24          Printf.@printf("\nHamper %d value %d:\n",hamperNumber,value)
25          for unit in hamper
26              Printf.@printf("%-25s%-25s%7d\n",unit.item,unit.brand,unit.price)
27          end
28          Printf.@printf("Remaining units %d\n",length(units))
29      end
```
Some clarification, by line numbers:
* Lines 13: Set up the ideal and maximum values to be loaded into any given hamper and initialize Groovy's random number generator and the hamper number
* Lines 429: This `while` loop redistributes units into hampers, as long as there are more available
* Lines 57: Increment the (global) hamper number, get a new empty hamper (an array of `Unit` instances), and set its value to 0
* Line 8 and 923: As long as I can add units to the hamper…
* Line 10: Gets a random number between zero and the number of remaining units minus 1
* Line 11: Assumes I can't find more units to add
* Lines 1222: This `for` loop, starting at the randomly chosen index, will try to find a unit that can be added to the hamper
* Lines 1314: Figure out which unit to look at (remember arrays start at index 1) and get it
* Lines 1521: I can add this unit to the hamper if there are only a few left or if the value of the hamper isn't too high once the unit is added and if that unit isn't already in the hamper
* Lines 1618: Add the unit to the hamper, increment the hamper value by the unit price, and remove the unit from the available units list
* Lines 1920: As long as there are units left, I can add more, so break out of this loop to keep looking
* Line 22: On exit from this `for` loop, if I have inspected every remaining unit and could not find one to add to the hamper, the hamper is complete; otherwise, I found one and can continue looking for more
* Line 23: On exit from this `while` loop, the hamper is as full as I can make it, so…
* Lines 2428: Print out the contents of the hamper and the remaining units info
* Line 29: When I exit this loop, there are no more units left
The output of running this code looks quite similar to the output from the other programs:
```
Hamper 1 value 5020:
Tea                      Superior                     544
Sugar                    Good Price                   565
Soap                     Sunny Day                    299
Chickpeas                Southern Style              1300
Flour                    Neighbor Mills               520
Rice                     Best Family                  565
Spaghetti                Best Family                  327
Bleach                   Blanchite                    710
Tomato sauce             Best Family                  190
Remaining units 146
Hamper 2 value 5314:
Flour                    Neighbor Mills               520
Sugar                    Good Price                   565
Vegetable oil            Crafco                       835
Coffee                   Colombia Select             2090
UHT milk                 Atlantic                     760
Tea                      Superior                     544
Remaining units 140
Hamper 3 value 5298:
Tomato sauce             Best Family                  190
Tofu                     Gourmet Choice              1580
Sugar                    Good Price                   565
Bleach                   Blanchite                    710
Tea                      Superior                     544
Lentils                  Southern Style              1189
Flour                    Neighbor Mills               520
Remaining units 133
Hamper 23 value 4624:
Chickpeas                Southern Style              1300
Vegetable oil            Crafco                       835
Tofu                     Gourmet Choice              1580
Sardines                 Fresh Caught                 909
Remaining units 4
Hamper 24 value 5015:
Tofu                     Gourmet Choice              1580
Chickpeas                Southern Style              1300
Chickpeas                Southern Style              1300
Vegetable oil            Crafco                       835
Remaining units 0
```
The last hamper is abbreviated in contents and value.
### Closing thoughts
Once again, the random-number-driven list manipulation seems to make the "working code" portion of the program pretty similar to the Groovy, Python, and Java versions. To my delight, I found good functional programming support in Julia, at least with respect to the straightforward list processing required for this small problem.
Given that the main effort revolves around `for` and `while` loops, in Julia, I don't see any construct similar to:
```
for (boolean canAdd = true; canAdd; ) { … }
```
This means I have to declare the `canAdd` variable outside the `while` loop. Which is too bad—but not a terrible thing.
I do miss not being able to attach behavior directly to my data, but that's just my appreciation for object-oriented programming showing through. It's certainly not a huge impediment in this program; however, correspondence with a kind author about my Java version made me realize that I should have built a class to fully encapsulate the distribution function into something like a list of hampers, which the main program would just print out. This approach would not be feasible in a non-object-oriented language like Julia.
Good things: low ceremony, check; decent list-handling, check; compact and readable code, check. All in all, a pleasant experience, supporting the idea that Julia can be a decent choice to solve "ordinary problems" and as a scripting language.
Next time, I'll do this exercise in [Go][6].
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/1/solve-problem-julia
作者:[Chris Hermansen][a]
选题:[lkxed][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/clhermansen
[b]: https://github.com/lkxed
[1]: https://opensource.com/sites/default/files/lead-images/puzzle_computer_solve_fix_tool.png
[2]: https://opensource.com/article/20/9/groovy
[3]: https://opensource.com/article/20/9/solve-problem-python
[4]: https://opensource.com/article/20/9/problem-solving-java
[5]: https://julialang.org/
[6]: https://golang.org/

View File

@@ -1,180 +0,0 @@
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (A few bytes here, a few there, pretty soon youre talking real memory)
[#]: via: (https://dave.cheney.net/2021/01/05/a-few-bytes-here-a-few-there-pretty-soon-youre-talking-real-memory)
[#]: author: (Dave Cheney https://dave.cheney.net/author/davecheney)
A few bytes here, a few there, pretty soon youre talking real memory
======
Todays post comes from a recent Go pop quiz. Consider this benchmark fragment.[1][1]
```
func BenchmarkSortStrings(b *testing.B) {
s := []string{"heart", "lungs", "brain", "kidneys", "pancreas"}
b.ReportAllocs()
for i := 0; i < b.N; i++ {
sort.Strings(s)
}
}
```
A convenience wrapper around `sort.Sort(sort.StringSlice(s))`, `sort.Strings` sorts the input in place, so it isnt expected to allocate (or at least thats what 43% of the tweeps who responded thought). However it turns out that, at least in recent versions of Go, each iteration of the benchmark causes one heap allocation. Why does this happen?
Interfaces, as all Go programmers should know, are implemented as a [two word structure][2]. Each interface value contains a field which holds the type of the interfaces contents, and a pointer to the interfaces contents.[2][3]
In pseudo Go code, an interface might look something like this:
```
type interface struct {
// the ordinal number for the type of the value
// assigned to the interface
type uintptr
// (usually) a pointer to the value assigned to
// the interface
data uintptr
}
```
`interface.data` can hold one machine word8 bytes in most casesbut a `[]string` is 24 bytes; one word for the pointer to the slices underlying array; one word for the length; and one for the remaining capacity of the underlying array, so how does Go fit 24 bytes into 8? With the oldest trick in the book, indirection. `s`, a `[]string` is 24 bytes, but `*[]string`a pointer to a slice of stringsis only 8.
### Escaping to the heap
To make the example a little more explicit, heres the benchmark rewritten without the `sort.Strings` helper function:
```
func BenchmarkSortStrings(b *testing.B) {
s := []string{"heart", "lungs", "brain", "kidneys", "pancreas"}
b.ReportAllocs()
for i := 0; i < b.N; i++ {
var ss sort.StringSlice = s
var si sort.Interface = ss // allocation
sort.Sort(si)
}
}
```
To make the interface magic work, the compiler rewrites the assignment as `var si sort.Interface = &ss`the _address_ of `ss` is assigned to the interface value.[3][4] We now have a situation where the interface value holds a pointer to `ss`, but where does it point? Where in memory does `ss` live?
It appears that `ss` is moved to the heap, causing the allocation that the benchmark reports.
```
Total: 296.01MB 296.01MB (flat, cum) 99.66%
8 . . func BenchmarkSortStrings(b *testing.B) {
9 . . s := []string{"heart", "lungs", "brain", "kidneys", "pancreas"}
10 . . b.ReportAllocs()
11 . . for i := 0; i < b.N; i++ {
12 . . var ss sort.StringSlice = s
13 296.01MB 296.01MB var si sort.Interface = ss // allocation
14 . . sort.Sort(si)
15 . . }
16 . . }
```
The allocation occurs because the compiler currently cannot convince itself that `ss` outlives `si`. The general attitude amongst Go compiler hackers seems to be that [this could be improved][5], but thats a discussion for another time. As it stands, `ss` is allocated on the heap. Thus the question becomes, how many bytes are allocated per iteration? Why dont we ask the `testing` package.
```
% go test -bench=. sort_test.go
goos: darwin
goarch: amd64
cpu: Intel(R) Core(TM) i7-5650U CPU @ 2.20GHz
BenchmarkSortStrings-4 12591951 91.36 ns/op 24 B/op 1 allocs/op
PASS
ok command-line-arguments 1.260s
```
Using Go 1.16beta1, on amd64, 24 bytes are allocated per operation.[4][6] However, the previous Go version, on the same platform, consumes 32 bytes per operation
```
% go1.15 test -bench=. sort_test.go
goos: darwin
goarch: amd64
BenchmarkSortStrings-4 11453016 96.4 ns/op 32 B/op 1 allocs/op
PASS
ok command-line-arguments 1.225s
```
This brings us, circuitously, to the subject of this post, a nifty quality of life improvement coming in Go 1.16. But before I can talk about it, I need to discuss size classes.
### Size classes
To explain what a size class is, consider how a theoretical Go runtime could allocate 24 bytes on its heap. A simple way to do this would be keep track of all the memory allocated so far using a pointer to the last allocated byte on the heap. To allocate 24 bytes, the heap pointer is incremented by 24, and the previous value returned to the caller. As long as the code that asked for 24 bytes never writes beyond that mark this mechanism has no overhead. Sadly, in real life, memory allocators dont just allocate memory, sometimes they have to free it.
Eventually the Go runtime will have to free those 24 bytes, but from the runtimes point of view, the only thing it knows is the starting address it gave to the caller. It does not know how many bytes after that address were allocated. To permit deallocation, our hypothetical Go runtime allocator would have to record, for each allocation on the heap, its length. Where are the allocation for those lengths allocated? On the heap of course.
In our scenario, when the runtime wants to allocate memory, it could request a little more than it was asked for and use it to store the amount requested. For our slice example, when we asked for 24 bytes, wed actually consume 24 bytes plus some overhead to store the number 24. How large is this overhead? It turns out the minimum amount that is practical is one word.[5][7]
To record a 24 byte allocation the overhead would 8 bytes. 25% is not great, but not terrible, and as the size of the allocation goes up, the overhead would become insignificant. However, what would happen if we wanted to store just one `byte` on the heap? The overhead would be eight times the amount of data we asked for! Is there are more efficient way to allocate small amounts on the heap?
Rather than storing the length alongside each allocation, what if all the thing of the same size were stored together? If all the 24 byte things are stored together, then the runtime would automatically know how large they are. All the runtime needs is a single bit to indicate if a 24 byte area is in use or not. In Go these areas are known as size classes, because all the things of the same size are stored together (think school classall the students are the same gradenot a C++ class). When the runtime needs to allocate a small amount, it does so using the smallest size class that can accomodate the allocation.
### Unlimited size classes for all
Now we know how size classes work, the obvious question is, where are they stored? Not surprisingly, the memory for a size class comes from the heap. To minimise overhead, the runtime allocates a larger amount from the heap (usually a multiple of the system page size) then dedicates that space for allocations of a single size. But, theres a problem.
The pattern of allocating a large area to store things of the same size works well[6][8] if theres a fixed, preferably small, number of allocation sizes, but in a general purpose language programs can ask the runtime for an allocation of any size.[7][9]
For example, imagine asking the runtime for 9 bytes. 9 bytes is an uncommon size, so its likely that a new size class for things of size 9 would be required. As 9 byte things are uncommon, its likely the remainder of the allocation, 4kb or more, would be wasted. Because of this the set of possible size classes is fixed. If a size class of the exact amount is not available, the allocation is rounded up to the next size class. In our example 9 bytes might be allocated in the 12 byte size class. The overhead of 3 unused bytes is better than an entire size class allocation which goes mostly unused.
### All together now
This is the final piece of the puzzle. Go 1.15 did not have a 24 byte size class, so the heap allocation of `ss` was allocated in the 32 byte size class. Thanks to the work of Martin Möhrmann Go 1.16 has a 24 byte size class, which is a perfect fit for slice values assigned to interfaces.
1. This is not the correct way to benchmark a sort function because after the first iteration, the input is sorted. But I digress.[][10]
2. The accuracy of this statement depends on the version of Go in use. For example, Go 1.15 added the ability to [store some integers directly in the interface value,][11] saving the allocation and indirection. However, for the majority of values, if it wasnt a pointer type already, its address is taken and stored in the interface value.[][12]
3. The compiler keeps track of this sleight of hand in the interface values type field so it remembers that the type assigned to `si` is `sort.StringSlice`, not `*sort.StringSlice`.[][13]
4. On 32 bit platforms this number is halved, [but we never look back][14].[][15]
5. If you were prepared to limit allocations to 4G, or maybe 64kb, you could use a smaller amount of memory to store the size of the allocation, but this would mean the first word of the allocation is not naturally aligned so in practice the savings of using less than a word to store the length header are undermined by padding.[][16]
6. Storing things of the same size together is also an effective strategy to combat fragmentation.[][17]
7. This isnt a far fetched scenario, strings come in all shapes and sizes and generating a string of a size not previously seen before can be as simple as appending a space.[][18]
#### Related posts:
1. [Im talking about Go at DevFest Siberia 2017][19]
2. [If aligned memory writes are atomic, why do we need the sync/atomic package?][20]
3. [A real serial console for your Raspberry Pi][21]
4. [Why is a Goroutines stack infinite ?][22]
--------------------------------------------------------------------------------
via: https://dave.cheney.net/2021/01/05/a-few-bytes-here-a-few-there-pretty-soon-youre-talking-real-memory
作者:[Dave Cheney][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://dave.cheney.net/author/davecheney
[b]: https://github.com/lujun9972
[1]: tmp.AZQSXjFgPm#easy-footnote-bottom-1-4231 (This is not the correct way to benchmark a sort function because after the first iteration, the input is sorted. But I digress.)
[2]: https://research.swtch.com/interfaces
[3]: tmp.AZQSXjFgPm#easy-footnote-bottom-2-4231 (The accuracy of this statement depends on the version of Go in use. For example, Go 1.15 added the ability to <a href="https://golang.org/doc/go1.15#runtime">store some integers directly in the interface value,</a> saving the allocation and indirection. However, for the majority of values, if it wasnt a pointer type already, its address is taken and stored in the interface value.)
[4]: tmp.AZQSXjFgPm#easy-footnote-bottom-3-4231 (The compiler keeps track of this sleight of hand in the interface values type field so it remembers that the type assigned to <code>si</code> is <code>sort.StringSlice</code>, not <code>*sort.StringSlice</code>.)
[5]: https://github.com/golang/go/issues/23676
[6]: tmp.AZQSXjFgPm#easy-footnote-bottom-4-4231 (On 32 bit platforms this number is halved, <a href="https://www.tallengestore.com/products/i-never-look-back-darling-it-distracts-from-the-now-edna-mode-inspirational-quote-tallenge-motivational-poster-collection-large-art-prints">but we never look back</a>.)
[7]: tmp.AZQSXjFgPm#easy-footnote-bottom-5-4231 (If you were prepared to limit allocations to 4G, or maybe 64kb, you could use a smaller amount of memory to store the size of the allocation, but this would mean the first word of the allocation is not naturally aligned so in practice the savings of using less than a word to store the length header are undermined by padding.)
[8]: tmp.AZQSXjFgPm#easy-footnote-bottom-6-4231 (Storing things of the same size together is also an effective strategy to combat fragmentation.)
[9]: tmp.AZQSXjFgPm#easy-footnote-bottom-7-4231 (This isnt a far fetched scenario, strings come in all shapes and sizes and generating a string of a size not previously seen before can be as simple as appending a space.)
[10]: tmp.AZQSXjFgPm#easy-footnote-1-4231
[11]: https://golang.org/doc/go1.15#runtime
[12]: tmp.AZQSXjFgPm#easy-footnote-2-4231
[13]: tmp.AZQSXjFgPm#easy-footnote-3-4231
[14]: https://www.tallengestore.com/products/i-never-look-back-darling-it-distracts-from-the-now-edna-mode-inspirational-quote-tallenge-motivational-poster-collection-large-art-prints
[15]: tmp.AZQSXjFgPm#easy-footnote-4-4231
[16]: tmp.AZQSXjFgPm#easy-footnote-5-4231
[17]: tmp.AZQSXjFgPm#easy-footnote-6-4231
[18]: tmp.AZQSXjFgPm#easy-footnote-7-4231
[19]: https://dave.cheney.net/2017/08/23/im-talking-about-go-at-devfest-siberia-2017 (Im talking about Go at DevFest Siberia 2017)
[20]: https://dave.cheney.net/2018/01/06/if-aligned-memory-writes-are-atomic-why-do-we-need-the-sync-atomic-package (If aligned memory writes are atomic, why do we need the sync/atomic package?)
[21]: https://dave.cheney.net/2014/01/05/a-real-serial-console-for-your-raspberry-pi (A real serial console for your Raspberry Pi)
[22]: https://dave.cheney.net/2013/06/02/why-is-a-goroutines-stack-infinite (Why is a Goroutines stack infinite ?)

View File

@@ -1,399 +0,0 @@
[#]: subject: "How to customize your voice assistant with the voice of your choice"
[#]: via: "https://opensource.com/article/21/1/customize-voice-assistant"
[#]: author: "Rich Lucente https://opensource.com/users/rlucente"
[#]: collector: "lkxed"
[#]: translator: " "
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
How to customize your voice assistant with the voice of your choice
======
The Nana and Poppy project enables a voice assistant to greet users with their great-grandchildren's voices instead of a generic AI.
![radio communication signals][1]
Image by: [Internet Archive Book Images][2]. Modified by Opensource.com. [CC BY-SA 4.0][3]
It can be hard to find meaningful gifts for relatives that already have almost everything. My wife and I have given our parents "experiences" to try something novel, such as going to a themed restaurant or seeing a concert, but as our parents get older, it becomes more difficult. This year was no exception—until I thought about a way open source could give them something really special.
What if when they request help from an artificial intelligence (AI) voice assistant such as [Mycroft][4], my in-laws could get a special greeting? I looked at the existing voice assistant APIs to see if something like this was already available. There was something close, but not exactly what I was looking for. My idea was to record their great-grandchildren speaking a short greeting that would play whenever they push the button and before the conversation with the voice assistant begins. The greeting would be something like:
> "Good morning, Nana and Poppy. Today is December 25th. The time is 3:10 pm. The current temperature for Waynesboro is 47 degrees. The current temperature for Ocean City is 50 degrees."
When they press the button, my in-laws would hear their great-grandchildren reporting the date, time, and temperature for their home and their favorite vacation spot. To make this a reality, I had to solve a few problems.
### So many audio files…
The first problem was figuring out what phrases the voice assistant would need to say. Thinking about all the dates, times, and temperatures that I would need to cover, I arrived at a list of 79 phrases. I sent these instructions to my nieces:
> Please record the kids saying each line below. Sorry there are so many. It's okay to do this in one setting with prompting them if it makes it easier. I can edit the audio files and deal with most formats, so none of that should be a problem. Just record using your phone in whatever way is easiest.
> Make sure that the kids say each line clearly and loudly. There should be a slight pause between each line to make editing easier (prompting helps like "Repeat after me …"). That will make it easier for me to chop these up into individual sound files.*
> Whenever the button on the device is pushed, it will respond with a random grandchild saying the correct date/time/temperature, like: "Good afternoon, Nana and Poppy. Today is January third. The time is one oh four pm. The current temperature for Waynesboro is thirty degrees. The current temperature for Ocean City is thirty four degrees."
> PLEASE RECORD EACH CHILD SAYING THE FOLLOWING PHRASES WITH A SHORT PAUSE BETWEEN EACH ONE:
Then I provided the following list of words for the children to record:
(这个表格有问题,待修复)
| - | - | - |
| :- | :- | :- |
| Good
morning
afternoon
evening
night
Nana and Poppy
The time
Today 
The current temperature for
Waynesboro
Ocean City
is
and
degrees
minus
am
pm
January
February
March
April
May | June
July
August
September
October
November
December
first
second
third
fourth
fifth
sixth
seventh
eighth
ninth
tenth
eleventh
twelfth
thirteenth
fourteenth
fifteenth
sixteenth
seventeenth
eighteenth
nineteenth
twentieth
thirtieth
oh | one
two
three
four
five
six
seven
eight
nine
ten
eleven
twelve
thirteen
fourteen
fifteen
sixteen
seventeen
eighteen
nineteen
twenty
thirty
forty
fifty
sixty
seventy
eighty
ninety
hundred |
*Nana and Poppy*
*The time
Today 
The current temperature for
Waynesboro
Ocean City
is
and
degrees
minus*
*am
pm*
*January
February
March
April
May*
My nieces are doubly blessed with children under 10 years old and near-infinite patience. So, after a couple of months of prodding, I received a three-minute audio file for each child.
Now my problem was how to edit them. I needed to normalize the recordings, reduce noise, and chop them into audio clips for individual words and phrases. I also wanted to take advantage of lossless audio, and I decided to convert the tracks to Waveform Audio File Format ([WAV][5]). Audacity was just the open source tool to do all of that.
### Audacity to the rescue!
[Audacity][6] is a feature-rich open source sound-editing tool. The software's features and capabilities can be overwhelming, so I'll describe the workflow I followed to accomplish my goals. I make no claims to being an Audacity expert, but the steps I followed seemed to work pretty well. (Comments are always welcome on how to improve what I've done.)
Audacity has [downloads][7] for Linux, Windows, and macOS. I grabbed the most recent macOS binary and quickly installed it on my laptop. Launching Audacity opens an empty new project. I imported all of the children's audio files using the **Import** feature.
![Import audio files in Audacity][8]
#### Normalizing audio files
Some of the children spoke louder than others, so the various audio files had different volume levels. I needed to normalize the audio tracks so that the greeting's volume would be the same regardless of which child was speaking. To normalize the volumes, I began by selecting all of the audio tracks after they were imported.
![Selecting all the audio tracks][9]
To normalize the children's peaks and valleys, so one child wasn't louder than the other, I used Audacity's **Normalize** effect.
![Normalize effect][10]
It's important to understand that the Normalize and Amplify effects do very different things. Normalize adjusts the highest peaks and lowest valleys for multiple tracks, so they are all similar, whereas Amplify exaggerates the existing peaks and valleys. If I had used Amplify instead of Normalize, the louder child would have become even louder. I used the default settings to normalize the two audio tracks.
![Normalize defaults][11]
#### Remove background noise
Another thing I noticed is that there was noise between the spoken phrases on the tracks. Audacity has tooling to help reduce background noise and result in much cleaner audio. To reduce noise, select a sample of an audio track with background noise. I used the **View->Zoom** menu option to see the track's noise more easily.
![Background noise sample][12]
To make sure I selected only the background noise, I listened to the selected audio clip using the **Play** button in the toolbar. Next, I selected **Effect->Noise Reduction**.
![Noise Reduction effect][13]
Then I created a **Noise Profile** using step 1 in the **Noise Reduction** dialog.
![Get a Noise Profile from audio sample][14]
Audacity characterizes the background noise in the audio sample so that it can be removed. To remove the background noise, I selected the entire audio track by pressing the small **Select** button to the left of the track.
![Select whole audio track button][15]
I applied the **Noise Reduction** effect again, but this time I pressed **OK** in step 2 of the dialog. I accepted the default settings.
![Noise Reduction effect step 2][16]
I repeated these steps for each child's audio track, so I had normalized audio tracks, and the background noise was characterized and removed.
#### Export the clips as WAV files
The remaining task was to zoom and scroll through each track and export the specific clips as separate audio files in WAV format. When working with one child's track, I needed to mute the other tracks using either the small **Mute** button to the left of each audio track or, since there were so many tracks, selecting the **Solo** button for the track I wanted to work with.
![Mute and Solo buttons for multiple tracks][17]
Selecting each word and phrase can be tricky, but the ability to zoom into an audio track was my friend. I tried to set each audio clip's start and end to just before and just after the word or phrase being spoken. Before exporting any audio clips, I played the selected clip using the **Play** icon on the toolbar to make sure I got it all.
One interesting thing is how waveforms map to spoken words. The waveforms for "six" and "sixth" are incredibly similar, with the latter having a smaller audio waveform to the right for the "th" sound. I carefully tested each clip before exporting it to make sure I had captured the full word or phrase.
After selecting an audio clip for a word or phrase, I exported the selected audio using the **File->Export** menu.
![Exporting selected audio][18]
I had to make sure to save each clip using the correct file name from the list of words and phrases. This is because the application I used to customize the voice assistant expects the file name to match an entry in the phrase list.
The expected file names for the audio clips (without the .wav extension) are listed below. Note the underscores within the phrases. If you're doing this project, adjust the bold file names to match your loved ones' nicknames and location preferences. You'll also have to make the same changes in the application source code.
(这个表格有问题,待修正)
| - | - | - |
| :- | :- | :- |
| good
morning
afternoon
evening
night
nana_and_poppy
the_time
today
the_current_temperature_for
waynesboro
ocean_city
is
and
degrees
minus
am
pm
january
february
march
april
may
june
july
august
september
october | november
december
first
second
third
fourth
fifth
sixth
seventh
eighth
ninth
tenth
eleventh
twelfth
thirteenth
fourteenth
fifteenth
sixteenth
seventeenth
eighteenth
nineteenth
twentieth
thirtieth
oh
one
two | three
four
five
six
seven
eight
nine
ten
eleven
twelve
thirteen
fourteen
fifteen
sixteen
seventeen
eighteen
nineteen
twenty
thirty
forty
fifty
sixty
seventy
eighty
ninety
hundred |
This project's GitHub repository also includes a Bash script to run as a sanity check for any missing or misnamed files.
After choosing each clip's appropriate name, I saved the clip in the child's specific folder (child1, child2, etc.) as a WAV format file. I accepted the default export settings.
![Converting clip to WAV format][19]
After exporting all the audio clips, I had a folder for each child that was fully populated with WAV files for the phrases above. This seems like a lot of work, but it took only about 90 minutes for each child, and I got way more efficient with each successive audio clip.
### Package the application
Now that I had the audio clips for the greeting, I needed to think about the application and how to package it. I also wanted an open source-friendly solution that was open to modification.
About two years ago, a colleague gave me a [Google AIY Voice Kit][20] that he grabbed from the clearance bin for just $10. It's a cleverly folded box containing a speaker, microphone, and custom circuit board. You supply a Raspberry Pi and quickly have a do-it-yourself Google voice assistant. These kits are available for purchase online and in electronics stores. This small box offered an easy way to package the project.
![Google AIY Voice Kit][21]
### Customize the voice assistant
The Google kit includes a Python API and several Python modules. I followed the kit's instructions to get the initial configuration working. The [Google Assistant gRPC][22] software is open source under an Apache 2.0 license.
I adapted the Google Assistant gRPC demo to implement my application. The application's operation is fairly simple: First, it waits for the device's button to be pressed. The code then constructs four separate word lists for: 1. the greeting and date, 2. the current time, 3. the current temperature of the first location, and 4. the current temperature of the second location. The children's voices are randomly shuffled, and then each word list is used to play the audio clips corresponding to the child assigned to that list. (This is why it was important to strictly follow the naming convention for the audio clips.) The application then initiates a conversation with the Google Assistant API.
At first, I thought the code to gather weather data for the current temperature and convert numbers to words would be challenging. This proved not to be the case at all. In fact, existing open source Python modules made it all simple and intuitive.
There were two cases to be addressed for converting numbers to word lists: I needed to convert ordinal numbers to words (e.g., 1 and 2 to first and second), and I also needed to convert cardinal numbers to words (e.g., 28 to twenty-eight). The open source [inflect.py module][23] has functions that handle both cases quite easily.
```
import inflect
p = inflect.engine()
number = 23
# get a cardinal word list (e.g. ['twenty', 'three'])
print(p.number_to_words(number).replace('-', ' ').split(' '))
# get an ordinal word list (e.g. ['twenty', 'third'])
print(p.number_to_words(p.ordinal(number)).replace('-', ' ').split(' '))
```
The inflect engine returns string representations of the numbers with embedded hyphens (e.g., twenty-three) so that the code splits the strings into variable-length word lists by converting the hyphens to spaces and splitting the string into a list using a space as the delimiter.
The next problem to solve was getting the current temperature for the two locations. [Open Weather Map][24] offers a free-tier weather service that allows up to 60 calls a minute or 1 million calls a month, which is way more than this project needs. I signed up for the free-tier service and received an API key. It was very easy to access the service by using the open source Python wrapper module [PyOWM][25]. Here is a simplified code snippet:
```
import pyowm
# use the OpenWeatherMap API key to get a weather manager
owm = pyowm.OWM('YOUR-OPEN-WEATHER-MANAGER-API-KEY')
mgr = owm.weather_manager()
# convert location phrase to city for OWM API
# e.g. ocean_city becomes 'Ocean City, US'
location = 'ocean_city'
city = location.replace('_', ' ').title() + ', US'
# get current temperature in fahrenheit for location
observation = owm_mgr.weather_at_place(city)
temp = round(observation.weather.temperature('fahrenheit')['temp'])
```
### Wrapping it up with a bow
The full source code for the project is available in my [GitHub repository][26]. The project includes a systemd service unit file adapted from Google's demo to automatically start the application on device boot. The GitHub repository includes instructions to install the Python modules and configure the systemd service.
I created a [short video][27] of the result. Five custom voice assistants were distributed during the holidays: one each for the great grandparents and grandparents of each child. For some, these gifts brought tears of joy. The children's voices are absolutely adorable and these boxes capture a fleeting moment of childhood that can be enjoyed for a very long time.
Image by: (Rich Lucente, CC BY-SA 4.0)
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/1/customize-voice-assistant
作者:[Rich Lucente][a]
选题:[lkxed][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/rlucente
[b]: https://github.com/lkxed
[1]: https://opensource.com/sites/default/files/lead-images/sound-radio-noise-communication.png
[2]: https://www.flickr.com/photos/internetarchivebookimages/14571450820/in/photolist-ocCuEG-otg1AX-hPy8JE-oc9YmN-oeUU2C-8cKWej-hQz72S-rpae2k-ocNYbT-oxbPTB-odGRsQ-ouDBo1-i5GTL8-qscJfA-idDrfk-i5D6oK-6K6iNH-ouxpn7-i8SivQ-oeY1eG-i7HGbT-bqXPhH-hN5on7-i9Q8YD-ouFYDw-fpy7Lo-oeSJo1-otqUu4-hNaVhf-oydqAV-owur2M-owkTSD-oydSWR-ocayce-ovFdYk-ocdaeL-ouE9UP-zmmrhp-qxtozB-ouqnSQ-obYbwS-odrnXt-ousXXw-ocA6Uo-owme9S-ouACY2-ocajY1-oeUJQG-ouryBk-ouxMJb
[3]: https://creativecommons.org/licenses/by-sa/4.0/
[4]: https://opensource.com/article/20/7/mycroft-voice-skill
[5]: https://en.wikipedia.org/wiki/WAV
[6]: https://www.audacityteam.org/
[7]: https://www.audacityteam.org/download/
[8]: https://opensource.com/sites/default/files/uploads/audacity1_importaudio.png
[9]: https://opensource.com/sites/default/files/uploads/audacity2_selectingtracks.png
[10]: https://opensource.com/sites/default/files/uploads/audacity3_normalize.png
[11]: https://opensource.com/sites/default/files/uploads/audacity4_normalizedefaults.png
[12]: https://opensource.com/sites/default/files/uploads/audacity5_backgroundnoise.png
[13]: https://opensource.com/sites/default/files/uploads/audacity6_noisereduction.png
[14]: https://opensource.com/sites/default/files/uploads/audacity7_noiseprofile.png
[15]: https://opensource.com/sites/default/files/uploads/audacity8_selecttrack.png
[16]: https://opensource.com/sites/default/files/uploads/audacity9_noisereduction2.png
[17]: https://opensource.com/sites/default/files/uploads/audacity10_mutesolo.png
[18]: https://opensource.com/sites/default/files/uploads/audacity11_exportaudio.png
[19]: https://opensource.com/sites/default/files/uploads/audacity12_convertwav.png
[20]: https://aiyprojects.withgoogle.com/voice/
[21]: https://opensource.com/sites/default/files/uploads/googleaiy.png
[22]: https://pypi.org/project/google-assistant-grpc/
[23]: https://pypi.org/project/inflect
[24]: https://openweathermap.org/
[25]: https://pypi.org/project/pyowm
[26]: https://github.com/rlucente-se-jboss/nana-poppy-project
[27]: https://youtu.be/Co7rigJRNUM

View File

@@ -1,292 +0,0 @@
[#]: subject: "Analyze Kubernetes files for errors with KubeLinter"
[#]: via: "https://opensource.com/article/21/1/kubelinter"
[#]: author: "Jessica Cherry https://opensource.com/users/cherrybomb"
[#]: collector: "lkxed"
[#]: translator: " "
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
Analyze Kubernetes files for errors with KubeLinter
======
Find and fix errors in your Helm charts and Kubernetes configuration files with KubeLinter.
![magnifying glass on computer screen, finding a bug in the code][1]
Image by: Opensource.com
[KubeLinter][2] is an open source project released by Stackrox to analyze Kubernetes YAML files for security issues and errant code. The tool covers Helm charts and Kubernetes configuration files, including [Knative][3] files. Using it can improve cloud-native development, reduce development time, and encourage DevOps best practices.
### Download and install
For this tutorial, I used Pop_OS! 20.10, Helm 3, Go 1.13.8, and Minikube with Kubernetes 1.19.
You have several options to install KubeLinter.
You can install manually from the Git repository:
```
$ git clone git@github.com:stackrox/kube-linter.git
$ cd kube-linter && make build
$ .gobin/kube-linter version
```
If you use [Homebrew][4], you can install it with the `brew` command:
```
$ brew install kube-linter
```
You can also install it with Go (as I did):
```
$ GO111MODULE=on go get golang.stackrox.io/kube-linter/cmd/kube-linter
go: finding golang.stackrox.io/kube-linter latest
go: downloading golang.stackrox.io/kube-linter v0.0.0-20201204022312-475075c74675
go: extracting golang.stackrox.io/kube-linter v0.0.0-20201204022312-475075c74675
[...]
```
After installing, you must make an alias in your `~/.bashrc` :
```
$ echo "alias kube-linter=$HOME/go/bin/kube-linter" >> ~/.bashrc
$ source ~/.bashrc
```
### Helm with KubeLinter
Now that the tool is installed, try it out on a Helm chart. First, start Minikube with a clean build and some small configuration changes:
```
$ minikube config set kubernetes-version v1.19.0
$ minikube config set memory 8000
 These changes will take effect upon a minikube delete and then a minikube start
$ minikube config set cpus 12
 These changes will take effect upon a minikube delete and then a minikube start
$ minikube delete
?  Deleting "minikube" in docker ...
?  Deleting container "minikube" ...
?  Removing /home/jess/.minikube/machines/minikube ...
?  Removed all traces of the "minikube" cluster.
$ minikube start
?  minikube v1.14.2 on Debian bullseye/sid
 Using the docker driver based on user configuration
?  Starting control plane node minikube in cluster minikube
?  minikube 1.15.1 is available! Download it: https://github.com/kubernetes/minikube/releases/tag/v1.15.1
?  To disable this notice, run: 'minikube config set WantUpdateNotification false'
?  Downloading Kubernetes v1.19.0 preload ...
```
Once everything is running, create an example Helm chart called `first_test` :
```
$ helm create first_test
Creating first_test
$ ls
first_test
```
Test KubeLinter against the new, unedited chart. Run the `kube-linter` command to see the available commands and flags:
```
$ kube-linter
Usage:
  /home/jess/go/bin/kube-linter [command]
Available Commands:
  checks      View more information on lint checks
  help  Help about any command
  lint  Lint Kubernetes YAML files and Helm charts
  templates   View more information on check templates
  version     Print version and exit
Flags:
  -h, --help   help for /home/jess/go/bin/kube-linter
Use "/home/jess/go/bin/kube-linter [command] --help" for more information about a command.
```
Then test what the basic `lint` command does to your example chart. You'll end up with many errors, so I'll grab a snippet of some issues:
```
$ kube-linter lint first_test/
first_test/first_test/templates/deployment.yaml: (object: <no namespace>/test-release-first_test apps/v1, Kind=Deployment) container "first_test" does not have a read-only root file system (check: no-read-only-root-fs, remediation: Set readOnlyRootFilesystem to true in your container's securityContext.)
first_test/first_test/templates/deployment.yaml: (object: <no namespace>/test-release-first_test apps/v1, Kind=Deployment) container "first_test" is not set to runAsNonRoot (check: run-as-non-root, remediation: Set runAsUser to a non-zero number, and runAsNonRoot to true, in your pod or container securityContext. See https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ for more details.)
[...]
Error: found 12 lint errors
```
For the sake of brevity, I picked two security issues that are easy for me to fix. Over time, as you test more, you'll be able to fix any issues you find.
The `kube-linter` output provides hints about the required fixes. For instance, the first error ends with:
```
remediation: Set readOnlyRootFilesystem to true in your container's securityContext.
```
The next step is clear: Open the `values.yaml` file in a text editor (I use Vi, but you can use whatever you like) and locate the `securityContext` section:
```
securityContext: {}
  # capabilities:
  #   drop:
  #   - ALL
  # readOnlyRootFilesystem: true
  # runAsNonRoot: true
  # runAsUser: 1000
```
Uncomment the section and remove the braces:
```
securityContext:
   capabilities:
     drop:
    - ALL
   readOnlyRootFilesystem: true
   runAsNonRoot: true
   runAsUser: 1000
```
Save the file and rerun the linter. Those errors no longer show up in the list, and the error count changes.
```
Error: found 10 lint errors
```
Congratulations! You have resolved security issues!
### Kubernetes with KubeLinter
This example uses an app file from my [previous article on Knative][5] to test against Kubernetes config files. I already have Knative up and running, so you may want to review that article if it's not running on your system.
I downloaded the Kourier service YAML file for this example:
```
$ ls
kourier.yaml   first_test
```
Start by running the linter against `kourier.yaml`. Again, there are several issues. I'll focus on resource problems:
```
$ kube-linter lint kourier.yaml
kourier.yaml: (object: kourier-system/3scale-kourier-gateway apps/v1, Kind=Deployment) container "kourier-gateway" has cpu limit 0 (check: unset-cpu-requirements, remediation: Set your container's CPU requests and limits depending on its requirements. See https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#requests-and-limits for more details.)
kourier.yaml: (object: kourier-system/3scale-kourier-gateway apps/v1, Kind=Deployment) container "kourier-gateway" has memory request 0 (check: unset-memory-requirements, remediation: Set your container's memory requests and limits depending on its requirements. See https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#requests-and-limits for more details.)
Error: found 12 lint errors
```
Since this is a single deployment file, you can edit it directly. Open it in a text editor and change the values in the file. The file is long, so I'll include only the parts that need to change.
Start with deployment:
```
apiVersion: apps/v1
kind: Deployment
metadata:
  name: 3scale-kourier-gateway
  namespace: kourier-system
  labels:
    networking.knative.dev/ingress-provider: kourier
[...]
```
The containers section has some problems:
```
spec:
containers:
- args:
 - --base-id 1
  - -c /tmp/config/envoy-bootstrap.yaml
  - --log-level info
  command:
 - /usr/local/bin/envoy
  image: docker.io/maistra/proxyv2-ubi8:1.1.5
  imagePullPolicy: Always
  name: kourier-gateway
  ports:
  - name: http2-external
    containerPort: 8080
    protocol: TCP
  - name: http2-internal
    containerPort: 8081
    protocol: TCP
  - name: https-external
    containerPort: 8443
    protocol: TCP
```
Add some specs to the container configuration:
```
spec:
containers:
- args:
 - --base-id 1
  - -c /tmp/config/envoy-bootstrap.yaml
  - --log-level info
  command:
 - /usr/local/bin/envoy
  image: docker.io/maistra/proxyv2-ubi8:1.1.5
  imagePullPolicy: Always
  name: kourier-gateway
  ports:
  - name: http2-external
    containerPort: 8080
    protocol: TCP
  - name: http2-internal
    containerPort: 8081
    protocol: TCP
  - name: https-external
    containerPort: 8443
    protocol: TCP
 resources:
    limits:
cpu: 100m
memory: 128Mi
    requests:
cpu: 100m
memory: 128Mi
```
When you rerun the linter, you'll notice these issues no longer show in the output, and the error count changes:
```
Error: found 8 lint errors
```
Congratulations! You have fixed resource issues in your Kubernetes file!
### Final thoughts
KubeLinter is a great tool and a great opportunity to start a new DevOps process to secure and resource-manage all of your Kubernetes' and applications' configurations. Adding this function to automated testing steps up your environment and DevOps cycle.
I think KubeLinter's best part is that each error message includes documentation, so even if you don't know what the error linting output means, the documentation helps you learn and plan ahead. I recommend this tool for everyday use and working with retroactive code.
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/1/kubelinter
作者:[Jessica Cherry][a]
选题:[lkxed][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/cherrybomb
[b]: https://github.com/lkxed
[1]: https://opensource.com/sites/default/files/lead-images/mistake_bug_fix_find_error.png
[2]: https://github.com/stackrox/kube-linter
[3]: https://knative.dev/
[4]: https://opensource.com/article/20/6/homebrew-linux
[5]: https://opensource.com/article/20/11/knative

View File

@@ -1,110 +0,0 @@
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (Discover Fedora Kinoite: a Silverblue variant with the KDE Plasma desktop)
[#]: via: (https://fedoramagazine.org/discover-fedora-kinoite/)
[#]: author: (Timothée Ravier https://fedoramagazine.org/author/siosm/)
Discover Fedora Kinoite: a Silverblue variant with the KDE Plasma desktop
======
![][1]
Photo by [Jaakko Kemppainen][2] on [Unsplash][3]
Fedora Kinoite is an immutable desktop operating system featuring the [KDE Plasma desktop][4]. In short, Fedora Kinoite is like Fedora Silverblue but with KDE instead of GNOME. It is an emerging variant of Fedora, based on the same technologies as Fedora Silverblue (rpm-ostree, Flatpak, podman) and created exclusively from official RPM packages from Fedora.
### Fedora Kinoite is like Silverblue, but what is Silverblue?
From the [Fedora Silverblue documentation][5]:
> Fedora Silverblue is an immutable desktop operating system. It aims to be extremely stable and reliable. It also aims to be an excellent platform for developers and for those using container-focused workflows.
For more details about what makes Fedora Silverblue interesting, read the “[What is Fedora Silverblue?][6]” article previously published on Fedora Magazine. Everything in that article also applies to Fedora Kinoite.
### Fedora Kinoite status
Kinoite is not yet an official emerging edition of Fedora. But this is [in progress][7] and currently planned for Fedora 35. However, it is already usable! [Join us][8] if you want to help.
Kinoite is made from the same packages that are available in the Fedora repositories and that go into the classic Fedora KDE Plasma Spin, so it is as functional and stable as classic Fedora. Im also “eating my own dog food” as it is the only OS installed on the laptop that I am currently using to write this article.
However, be aware that Kinoite does not currently have graphical support for updates. You will need to be confortable with using the command line to manage updates, install Flatpaks, or overlay packages with rpm-ostree.
#### How to try Fedora Kinoite
As Kinoite is not yet an official Fedora edition, there is not a dedicated installer for it for now. To get started, [install Silverblue][9] and switch to Kinoite with the following commands:
```
# Add the temporary unofficial Kinoite remote
$ curl -O https://tim.siosm.fr/downloads/siosm_gpg.pub
$ sudo ostree remote add kinoite https://siosm.fr/kinoite/ --gpg-import siosm_gpg.pub
# Optional, only if you want to keep Silverblue available
$ sudo ostree admin pin 0
# Switch to Kinoite
$ sudo rpm-ostree rebase kinoite:fedora/33/x86_64/kinoite
# Reboot
$ sudo systemctl reboot
```
#### How to keep it up-to-date
Kinoite does not yet have graphical support for updates in Discover. Work is in progress to teach Discover how to manage an rpm-ostree system. Flatpak management mostly works with Discover but the command line is still the best option for now.
To update the system, use:
```
$ rpm-ostree update
```
To update Flatpaks, use:
```
$ flatpak update
```
### Status of KDE Apps Flatpaks
Just like Fedora Silverblue, Fedora Kinoite focuses on applications delivered as Flatpaks. Some non KDE applications are available in the Fedora Flatpak registry, but until this selection is expanded with KDE ones, your best bet is to look for them in [Flathub][10] (see all [KDE Apps on Flathub][11]). Be aware that applications on Flathub may include non-free or proprietary software. The KDE SIG is working on packaging KDE Apps [as Fedora provided Flatpaks][12] but this is not ready yet.
### Submitting bug reports
Report issues in the [Fedora KDE SIG issue tracker][13] or in the discussion thread at [discussion.fedoraproject.org][14].
### Other desktop variants
Although this project started with KDE, I have also already created variants for XFCE, Mate, Deepin, Pantheon, and LXQt. They are currently available from the same remote as Kinoite. Note that they will remain unofficial until someone steps up to maintain them officially in Fedora.
I have also created an additional smaller Base variant without any desktop environment. This allows you to overlay the lightweight window manager of your choice (i3, Sway, etc.). The same caveats as the ones for other desktop environments apply (currently unofficial and will need a maintainer).
--------------------------------------------------------------------------------
via: https://fedoramagazine.org/discover-fedora-kinoite/
作者:[Timothée Ravier][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://fedoramagazine.org/author/siosm/
[b]: https://github.com/lujun9972
[1]: https://fedoramagazine.org/wp-content/uploads/2021/01/kinoite-816x345.jpg
[2]: https://unsplash.com/@jaakkok?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText
[3]: https://unsplash.com/s/photos/crystal?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText
[4]: https://kde.org/plasma-desktop/
[5]: https://docs.fedoraproject.org/en-US/fedora-silverblue/
[6]: https://fedoramagazine.org/what-is-silverblue/
[7]: https://pagure.io/fedora-kde/SIG/issue/4
[8]: https://fedoraproject.org/wiki/SIGs/KDE
[9]: https://docs.fedoraproject.org/en-US/fedora-silverblue/installation/
[10]: https://flathub.org
[11]: https://flathub.org/apps/search/org.kde
[12]: https://pagure.io/fedora-kde/SIG/issue/13
[13]: https://pagure.io/fedora-kde/SIG
[14]: https://discussion.fedoraproject.org/t/kinoite-a-kde-and-now-xfce-version-of-fedora-silverblue/147

View File

@@ -1,110 +0,0 @@
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (Review of Container-to-Container Communications in Kubernetes)
[#]: via: (https://www.linux.com/news/review-of-container-to-container-communications-in-kubernetes/)
[#]: author: (LF Training https://training.linuxfoundation.org/announcements/review-of-container-to-container-communications-in-kubernetes/)
Review of Container-to-Container Communications in Kubernetes
======
This article was originally posted at [TheNewStack][1].
_By Matt Zand and Jim Sullivan_
Kubernetes is a containerized solution. It provides virtualized runtime environments called Pods, which house one or more containers to provide a virtual runtime environment. An important aspect of Kubernetes is container communication within the Pod. Additionally, an important area of managing the Kubernetes network is to forward container ports internally and externally to make sure containers within a Pod communicate with one another properly. To manage such communications, Kubernetes offers the following four networking models:
* Container-to-Container communications
* Pod-to-Pod communications
* Pod-to-Service communications
* External-to-Internal communications
In this article, we dive into Container-to-Container communications, by showing you ways in which containers within a pod can network and communicate.
### Communication Between Containers in a Pod
Having multiple containers in a single Pod makes it relatively straightforward for them to communicate with each other. They can do this using several different methods. In this article, we discuss two methods: i- Shared Volumes and ii-Inter-Process Communications in more detail.
#### **I- Shared Volumes in a Kubernetes Pod**
In Kubernetes, you can use a shared Kubernetes Volume as a simple and efficient way to share data between containers in a Pod. For most cases, it is sufficient to use a directory on the host that is shared with all containers within a Pod.
Kubernetes Volumes enables data to survive container restarts, but these volumes have the same lifetime as the Pod. This means that the volume (and the data it holds) exists exactly as long as that Pod exists. If that Pod is deleted for any reason, even if an identical replacement is created, the shared Volume is also destroyed and created from scratch.
A standard use case for a multicontainer Pod with a shared Volume is when one container writes logs or other files to the shared directory, and the other container reads from the shared directory. For example, we can create a Pod like so:
![][2]
In this example, we define a volume named html. Its type is emptyDir, which means that the Volume is first created when a Pod is assigned to a node and exists as long as that Pod is running on that node; as the name says, it is initially empty. The first container runs the Nginx server and has the shared Volume mounted to the directory /usr/share/nginx/html. The second container uses the Debian image and has the shared Volume mounted to the directory /html. Every second, the second container adds the current date and time into the index.html file, which is located in the shared Volume. When the user makes an HTTP request to the Pod, the Nginx server reads this file and transfers it back to the user in response to the request. [Here][3] is a good article for reading more on similar Kubernetes topics.
<https://cdn.thenewstack.io/media/2020/11/d5362cd2-image1.png>
You can check that the pod is working either by exposing the nginx port and accessing it using your browser, or by checking the shared directory directly in the containers:
#### **![][4]**
#### **II- Inter-Process Communications (IPC)**
Containers in a Pod share the same IPC namespace, which means they can also communicate with each other using standard inter-process communications such as SystemV semaphores or POSIX shared memory. Containers use the strategy of the localhost hostname for communication within a pod.
In the following example, we define a Pod with two containers. We use the same Docker image for both. The first container is a producer that creates a standard Linux message queue, writes a number of random messages, and then writes a special exit message. The second container is a consumer which opens that same message queue for reading and reads messages until it receives the exit message. We also set the restart policy to “Never”, so the Pod stops after the termination of both containers.
![][5]
To check this out, create the pod using kubectl create and watch the Pod status:
![][6]
Now you can check logs for each container and verify that the second container received all messages from the first container, including the exit message:
![][7]
<https://cdn.thenewstack.io/media/2020/11/6517d90b-image2.png>
There is one major problem with this Pod, however, and it has to do with how containers start up.
### **Conclusion**
The primary reason that Pods can have multiple containers is to support helper applications that assist a primary application. Typical examples of helper applications are data pullers, data pushers and proxies. An example of this pattern is a web server with a helper program that polls a git repository for new updates.
The Volume in this exercise provides a way for containers to communicate during the life of the Pod. If the Pod is deleted and recreated, any data stored in the shared Volume is lost. In this article, we also discussed the concept of Inter-Process Communications among containers within a Pod, which is an alternative to shared Volume concepts. Now that you learn how containers inside a Pod can communicate and exchange data, you can move on to learn other Kubernetes networking models — such as Pod-to-Pod or Pod-to-Service communications. [Here][8] is a good article for learning more advanced topics on Kubernetes development.
### **About the Authors**
**Matt Zand**
Matt is is a serial entrepreneur and the founder of three successful tech startups: DC Web Makers, Coding Bootcamps and High School Technology Services. He is a leading author of Hands-on Smart Contract Development with Hyperledger Fabric book by OReilly Media.
**Jim Sullivan**
Jim has a bachelors degree in Electrical Engineering and a Masters Degree in Computer Science. Jim also holds an MBA. Jim has been a practicing software engineer for 18 years. Currently, Jim leads an expert team in Blockchain development, DevOps, Cloud, application development, and the SAFe Agile methodology. Jim is an IBM Master Instructor.
The post [Review of Container-to-Container Communications in Kubernetes][9] appeared first on [Linux Foundation Training][10].
--------------------------------------------------------------------------------
via: https://www.linux.com/news/review-of-container-to-container-communications-in-kubernetes/
作者:[LF Training][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://training.linuxfoundation.org/announcements/review-of-container-to-container-communications-in-kubernetes/
[b]: https://github.com/lujun9972
[1]: https://thenewstack.io/review-of-container-to-container-communications-in-kubernetes/
[2]: https://training.linuxfoundation.org/wp-content/uploads/2020/12/fig1-300x243.png
[3]: https://myhsts.org/tutorial-review-of-17-essential-topics-for-mastering-kubernetes.php
[4]: https://training.linuxfoundation.org/wp-content/uploads/2020/12/fig2-300x54.png
[5]: https://training.linuxfoundation.org/wp-content/uploads/2020/12/fig3-300x130.png
[6]: https://training.linuxfoundation.org/wp-content/uploads/2020/12/fig4-300x54.png
[7]: https://training.linuxfoundation.org/wp-content/uploads/2020/12/fig5-300x129.png
[8]: https://blockchain.dcwebmakers.com/blog/advance-topics-for-deploying-and-managing-kubernetes-containers.html
[9]: https://training.linuxfoundation.org/announcements/review-of-container-to-container-communications-in-kubernetes/
[10]: https://training.linuxfoundation.org/

View File

@@ -1,210 +0,0 @@
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (Looking to Ditch WhatsApp? Here are 5 Better Privacy Alternatives to WhatsApp)
[#]: via: (https://itsfoss.com/private-whatsapp-alternatives/)
[#]: author: (Ankush Das https://itsfoss.com/author/ankush/)
Looking to Ditch WhatsApp? Here are 5 Better Privacy Alternatives to WhatsApp
======
After the latest [WhatsApp privacy policy updates][1], many users who trusted the service seem to be making the switch to alternatives like [Signal][2].
Even though WhatsApp tries to clarify and re-assure the change in the policies, users have made their mind while considering the benefits of using privacy alternatives to WhatsApp.
But, what are some useful and impressive alternatives to WhatsApp? In this article, let us take a look at some of the best options.
### Private messengers that do not violate your privacy
![][3]
There could be plenty of private messaging services. I have kept my focus on messaging services with the following criteria in mind:
* Mobile and desktop availability
* Group chats and channels
* Voice and video calls
* Emojis and sticker support
* Privacy and encryption
Basically, private messaging app that cater to the need of a common user.
#### 1\. Session
![][4]
**Key Features:**
* End-to-end Encryption
* Blockchain-based
* Decentralized
* Does not require phone number
* No data collected by Session
* Lets you create and manage open/closed groups (open groups are public channels)
* Voice messages
* Cross-platform with desktop apps
* **Open-Source**
Session is technically a fork of Signal and tries to go one step further by not requiring phone numbers. It isnt a typical WhatsApp replacement but if you want something different with privacy options, this could be it.
You will have to create a Session ID (that you can share to add contacts or ask your contacts to share theirs). If you delete the app, you will lose your ID, so you need to keep your recovery pass safely.
Unlike Signal, it does not rely on a centralized server but blockchain-based, i.e. decentralized. Thats good for reliability technically, but Ive noticed some significant delays in sending/receiving messages.
If youre tech-savvy, and want the absolute best for privacy, this could be it. But, it may not be a great option for elders and general consumers. For more information, you can check out my original [Session overview][5].
[Session][6]
#### 2\. Signal
![][7]
**Key Features:**
* End-to-End encryption
* Almost no data collection (Except your phone number)
* Supports Emojis and Stickers
* Lets you create and manage Groups
* Voice/Video calling supported
* Cross-platform support with desktop apps
* **Open-Source**
Signal is my personal favorite when it comes to privacy alternatives to WhatsApp. Ive made the switch for years, but I didnt have all my contacts in Signal. Fast-forward to 2021, I have most of my contacts on Signal.
Signal is the best blend of open-source and privacy. Theyve improved a lot over the years and is safe to assume as a perfect alternative to WhatsApp. You get almost every essential feature compared to WhatsApp.
However, just because it does not store your data, you may not be able to access all the messages of your smartphone on Desktop. In addition to that, it relies on local backup (which is protected by a passphrase) instead of cloud backups. So, you will have to head to the settings, start the backup, safely copy the passcode of the backup, check where the local backup gets stored, and make sure you dont delete it.
You can explore more about Signal in our [original coverage][2] and learn [how to install Signal in Linux][8].
[Signal][9]
**Recommended Read:**
![][10]
#### [9 Decentralized, P2P and Open Source Alternatives to Mainstream Social Media Platforms Like Twitter, Facebook, YouTube and Reddit][11]
#### 3\. Telegram
![][12]
**Key Features:**
* End-to-end Encryption (with Secret chat option)
* Cloud-based (no need to back up your chats, its all in the cloud)
* Ability to create public channels
* Create and manage groups
* Voice/Video Call
* Offers a better privacy policy to WhatsApp
* Supports Emojis and Stickers
* **Client-side Open-Source**
Telegram may not be the best bet for privacy, but it is certainly better than WhatsApp in several regards.
By default, the chats arent end-to-end encrypted but the convenience of having all the history in the cloud without needing to backup while having the secret chat option for encryption is a good deal for common consumers.
Not just limited to that, you also get native desktop apps and the client-side apps are open-source.
Of course, I wont recommend it over others for privacy-conscious users, but sometimes you just need a messenger that works, offers convenience, and respects the users privacy even if the chats are stored in the cloud.
[Telegram][13]
#### 4\. Threema (Paid)
![][14]
**Key Features:**
* End-to-end Encryption
* Does not require a phone number
* Lets you create and manage groups
* Ability to add polls
* Voice/Video calls
* **Switzerland-based** (known for best privacy policies)
* Cross-platform (with Threema Web for PC, no native desktop apps)
* **Open-Source**
Threema was among the best choices in the list of private messengers available out there. Initially, it wasnt open-source, which was a bummer.
But, now, Threema is completely open-source!
Threema offers the best features that youd always want in a messenger. However, it is a paid-only app.
Of course, if your friends/contacts do not mind paying for one of the best privacy alternatives to WhatsApp, you can easily recommend them this!
[Threema][15]
#### 5\. Element
![][16]
**Key Features:**
* End-to-end Encryption
* Does not require phone number
* Supports creating large public groups and closed groups as well
* Utilizes Decentralized [Matrix network][17]
* Voice/Video Calls
* Cross-platform with desktop apps
* **Open-Source**
Element is yet another fantastic WhatsApp alternative that is built keeping privacy in mind. It may not be a perfect replacement for a few contacts but if youre looking for an “All in One” platform for personal messaging and work as well, Element can be the perfect pick.
It was originally known as [Riot, and then it rebranded to Element][18]. Do note that it can be a little overwhelming if you wanted a simple alternative, but its great for privacy and security.
[Element][19]
### Wrapping Up
With the transparent policy updates to WhatsApp, more users are getting aware about the disadvantages of using a product owned by big tech companies. Hence, we need WhatsApp alternatives more than ever.
Of course, it is not easy to switch and convince other less tech-savvy users. But, it is certainly worth it.
What do you think about the best WhatsApp alternatives which offer better privacy? Let me know your thoughts in the comments below.
--------------------------------------------------------------------------------
via: https://itsfoss.com/private-whatsapp-alternatives/
作者:[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://fossbytes.com/whatsapp-privacy-policy-update/
[2]: https://itsfoss.com/signal-messaging-app/
[3]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/01/messaging-services.jpg?resize=800%2C450&ssl=1
[4]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2020/02/session-cross-platform.jpg?resize=800%2C444&ssl=1
[5]: https://itsfoss.com/session-messenger/
[6]: https://getsession.org/
[7]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/01/signal-messenger-new.jpg?resize=800%2C450&ssl=1
[8]: https://itsfoss.com/install-signal-ubuntu/
[9]: https://www.signal.org/
[10]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/01/1984-quote.png?fit=800%2C450&ssl=1
[11]: https://itsfoss.com/mainstream-social-media-alternaives/
[12]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/01/telegram-messenger.jpg?resize=800%2C450&ssl=1
[13]: https://telegram.org/
[14]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/01/threema.jpg?resize=800%2C450&ssl=1
[15]: https://threema.ch/
[16]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2020/07/element-apps.jpg?resize=799%2C480&ssl=1
[17]: https://matrix.org/
[18]: https://itsfoss.com/riot-to-element/
[19]: https://element.io/

View File

@@ -1,70 +0,0 @@
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (3 steps to achieving Inbox Zero)
[#]: via: (https://opensource.com/article/21/1/inbox-zero)
[#]: author: (Kevin Sonney https://opensource.com/users/ksonney)
3 steps to achieving Inbox Zero
======
Inbox Zero is a concept that helps you manage and prioritize all that
overwhelming email.
![Selfcare, drinking tea on the porch][1]
In prior years, this annual series covered individual apps. This year, we are looking at all-in-one solutions in addition to strategies to help in 2021. Welcome to day 7 of 21 Days of Productivity in 2021.
There are lots of ways people manage email. Most people I have talked to over the past few years fall into one of two categories: The people who keep everything in their Inbox folder, and those who do not. For those that do not, the concept of _Inbox Zero_ comes into play frequently.
Do you think the role you are responsible for at work -- developer, engineer, [SRE][2], [sysadmin][3], [product manager][4], [community manager][5], etc -- might play into which category someone falls into?
Inbox Zero is a term coined by Merlin Mann in 2006, and it _looks_ self-explanatory. Inbox Zero is an empty Inbox, right?
![Mailspring inbox zero][6]
Mailspring says I did it! (Kevin Sonney, [CC BY-SA 4.0][7])
If this were the case, Inbox Zero would be really easy to achieve. Just mark everything read and move it out of the Inbox. Who cares if it needs attention, scheduling, or some sort of action?
That is not the purpose of Inbox Zero. That is declaring [Inbox bankruptcy][8], a term popularized by Lawrence Lessig. Basically, Inbox bankruptcy is deciding there is too much to deal with, saying "to heck with it," and starting over from scratch.
Inbox Zero is about considering all the pending messages, deciding what to do with them, and then actually doing it. How can this be done quickly? My personal process is to scan everything and move anything that does not require action or my attention to a "Read Later" folder. These are usually messages like mailing lists, blog updates, and social network notifications. I can read them later if I have time or need a mental break from other things.
![Email folder setup][9]
My folder setup (Kevin Sonney, [CC BY-SA 4.0][7])
The next step is to start reading what is left. If the email is a task I can do in under two minutes, I just do it. This includes confirming or declining meetings, adding a conference link to a meeting, or simple queries that I can reply to right away. These all get moved or archived and are then out of the Inbox.
Finally, there should be a list of messages that require more in-depth thought, scheduling for the future, or lots of focus. These get put on my to-do list or calendar with deadline reminders, so I have dedicated time to work on them. Once these are scheduled, I move them to folders related to their topic. For me, these are tasks like reading comments on one of my podcasts, `git pull` requests, and lots of work-related emails.
![Inbox replenished][10]
Oh look, more email (Kevin Sonney, [CC BY-SA 4.0][7])
Hopefully, at this point, my Inbox is empty or close to it, and I can close my email program and not look at it for a few hours. As we discussed in an earlier post, email is not instant messaging and does not need monitoring 24x7.
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/1/inbox-zero
作者:[Kevin Sonney][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/ksonney
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/coffee_tea_selfcare_wfh_porch_520.png?itok=2qXG0T7u (Selfcare, drinking tea on the porch)
[2]: https://opensource.com/article/18/10/sre-startup
[3]: https://opensource.com/article/20/12/sysadmin
[4]: https://opensource.com/article/20/2/product-management-open-source-company
[5]: https://opensource.com/article/20/9/open-source-community-managers
[6]: https://opensource.com/sites/default/files/pictures/mailspring-inbox-zero.png (Mailspring inbox zero)
[7]: https://creativecommons.org/licenses/by-sa/4.0/
[8]: https://en.wikipedia.org/wiki/Email_bankruptcy
[9]: https://opensource.com/sites/default/files/pictures/email-folder-setup.png (Email folder setup)
[10]: https://opensource.com/sites/default/files/pictures/inbox-replenished.png (Inbox replenished)

View File

@@ -1,403 +0,0 @@
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (Deploy your own Matrix server on Fedora CoreOS)
[#]: via: (https://fedoramagazine.org/deploy-your-own-matrix-server-on-fedora-coreos/)
[#]: author: (Clément VernaTimothée Ravier https://fedoramagazine.org/author/cverna/https://fedoramagazine.org/author/siosm/)
Deploy your own Matrix server on Fedora CoreOS
======
![][1]
Today it is very common for open source projects to distribute their software via container images. But how can these containers be run securely in production? This article explains how to deploy a Matrix server on Fedora CoreOS.
### What is Matrix?
Matrix provides an open source, federated and optionally end-to-end encrypted communication platform.
From [matrix.org][2]:
> Matrix is an open source project that publishes the Matrix open standard for secure, decentralised, real-time communication, and its Apache licensed reference implementations.
Matrix also includes bridges to other popular platforms such as Slack, IRC, XMPP and Gitter. Some open source communities are replacing IRC with Matrix or adding Matrix as an new communication channel (see for example [Mozilla][3], [KDE][4], and Fedora).
Matrix is a [federated][5] communication platform. If you host your own server, you can join conversations hosted on other Matrix instances. This makes it great for self hosting.
### What is Fedora CoreOS?
From the [Fedora CoreOS docs][6]:
> Fedora CoreOS is an automatically updating, minimal, monolithic, container-focused operating system, designed for clusters but also operable standalone, optimized for Kubernetes but also great without it.
With Fedora CoreOS (FCOS), you get all the benefits of Fedora (podman, cgroups v2, SELinux) packaged in a minimal automatically updating system thanks to rpm-ostree.
To get more familiar with Fedora CoreOS basics, check out this getting started article:
> [Getting started with Fedora CoreOS][7]
### Creating the Fedora CoreOS configuration
Running a Matrix service requires the following software:
* [**Synapse**][8]: a Matrix server
* [**PostgreSQL**][9]: a database
* [**Nginx**][10]: a web server
* [**Lets Encrypt**][11]: a certificate provider
* [**Element**][12]: a Matrix web client
This guide will demonstrate how to run all of the above software in containers on the same FCOS server. All the services will all be configured to run under [podman][13] container engines.
### Assembling the FCCT configuration
Configuring and provisioning these containers on the host requires an [Ignition][14] file. [FCCT][15] generates the ignition file using a YAML configuration file as input. On Fedora Linux you can install FCCT using _dnf_:
```
$ sudo dnf install fcct
```
A [GitHub repository][16] is available for the reader, it contains all the configuration needed and a basic template system to simplify the personnalisation of the configuration. These template values use the _%%VARIABLE%%_ format and each variable is defined in a file named _[secrets][17]_.
#### User and ssh access
The first configuration step is to define an SSH key for the default user _core_.
```
variant: fcos
version: 1.3.0
passwd:
users:
- name: core
ssh_authorized_keys:
- %%SSH_PUBKEY%%
```
#### Cgroups v2
Fedora CoreOS comes with cgroups version 1 by default, but it can be configured to use cgroups v2. Using the latest version of cgroups allows for better control of the host resources among other new features.
Switching to cgroups v2 is done via a systemd service that modifies the kernel arguments and reboots the host on first boot.
```
systemd:
units:
- name: cgroups-v2-karg.service
enabled: true
contents: |
[Unit]
Description=Switch To cgroups v2
After=systemd-machine-id-commit.service
ConditionKernelCommandLine=systemd.unified_cgroup_hierarchy
ConditionPathExists=!/var/lib/cgroups-v2-karg.stamp
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/bin/rpm-ostree kargs --delete=systemd.unified_cgroup_hierarchy
ExecStart=/bin/touch /var/lib/cgroups-v2-karg.stamp
ExecStart=/bin/systemctl --no-block reboot
[Install]
WantedBy=multi-user.target
```
#### Podman pod
Podman supports the creation of pods. Pods are quite handy when you need to group containers together within the same network namespace. Containers within a pod can communicate with each other using the _localhost_ address.
Create and configure a pod to run the different services needed by Matrix:
```
- name: podmanpod.service
enabled: true
contents: |
[Unit]
Description=Creates a podman pod to run the matrix services.
After=cgroups-v2-karg.service network-online.target
Wants=After=cgroups-v2-karg.service network-online.target
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=sh -c 'podman pod exists matrix || podman pod create -n matrix -p 80:80 -p 443:443 -p 8448:8448'
[Install]
WantedBy=multi-user.target
```
Another advantage of using a pod is that we can control which ports are exposed to the host from the pod as a whole. Here we expose the ports 80, 443 (HTTP and HTTPS) and 8448 (Matrix federation) to the host to make these services available outside of the pod.
#### A web server with Lets Encrypt support
The Matrix protocol is HTTP based. Clients connect to their homeserver via HTTPS. Federation between Matrix homeservers is also done over HTTPS. For this setup, you will need three domains. Using distinct domains helps to isolate each service and protect against [cross-site scripting (XSS) vulnerabilities][18].
* **example.tld**: The base domain for your homeserver. This will be part of the user Matrix IDs (for example: @username:example.tld).
* **matrix.example.tld**: The sub-domain for your [Synapse][8] Matrix server.
* **chat.example.tld**: The sub-domain for your [Element][12] web client.
To simplify the configuration, you only need to set your own domain once in the secrets file.
You will need to ask Lets Encrypt for certificates on first boot for each of the three domains. Make sure that the domains are configured beforehand to resolve to the IP address that will be assigned to your server. If you do not know what IP address will be assigned to your server in advance, you might want to use another ACME challenge method to get Lets Encrypt certificates (see [DNS Plugins][19]).
```
- name: certbot-firstboot.service
enabled: true
contents: |
[Unit]
Description=Run certbot to get certificates
ConditionPathExists=!/var/srv/matrix/letsencrypt-certs/archive
After=podmanpod.service network-online.target nginx-http.service
Wants=network-online.target
Requires=podmanpod.service nginx-http.service
[Service]
Type=oneshot
ExecStart=/bin/podman run \
--name=certbot \
--pod=matrix \
--rm \
--cap-drop all \
--volume /var/srv/matrix/letsencrypt-webroot:/var/lib/letsencrypt:rw,z \
--volume /var/srv/matrix/letsencrypt-certs:/etc/letsencrypt:rw,z \
docker.io/certbot/certbot:latest \
--agree-tos --webroot certonly
[Install]
WantedBy=multi-user.target
```
Once the certificates are available, you can start the final instance of _nginx_. Nginx will act as an HTTPS reverse proxy for your services.
```
- name: nginx.service
enabled: true
contents: |
[Unit]
Description=Run the nginx server
After=podmanpod.service network-online.target certbot-firstboot.service
Wants=network-online.target
Requires=podmanpod.service certbot-firstboot.service
[Service]
ExecStartPre=/bin/podman pull docker.io/nginx:stable
ExecStart=/bin/podman run \
--name=nginx \
--pull=always \
--pod=matrix \
--rm \
--volume /var/srv/matrix/nginx/nginx.conf:/etc/nginx/nginx.conf:ro,z \
--volume /var/srv/matrix/nginx/dhparam:/etc/nginx/dhparam:ro,z \
--volume /var/srv/matrix/letsencrypt-webroot:/var/www:ro,z \
--volume /var/srv/matrix/letsencrypt-certs:/etc/letsencrypt:ro,z \
--volume /var/srv/matrix/well-known:/var/well-known:ro,z \
docker.io/nginx:stable
ExecStop=/bin/podman rm --force --ignore nginx
[Install]
WantedBy=multi-user.target
```
Because Lets Encrypt certificates have a short lifetime, they must be renewed frequently. Set up a system timer to automate their renewal:
```
- name: certbot.timer
enabled: true
contents: |
[Unit]
Description=Weekly check for certificates renewal
[Timer]
OnCalendar=Sun --* 02:00:00
Persistent=true
[Install]
WantedBy=timers.target
- name: certbot.service
enabled: false
contents: |
[Unit]
Description=Let's Encrypt certificate renewal
ConditionPathExists=/var/srv/matrix/letsencrypt-certs/archive
After=podmanpod.service network-online.target
Wants=network-online.target
Requires=podmanpod.service
[Service]
Type=oneshot
ExecStart=/bin/podman run \
--name=certbot \
--pod=matrix \
--rm \
--cap-drop all \
--volume /var/srv/matrix/letsencrypt-webroot:/var/lib/letsencrypt:rw,z \
--volume /var/srv/matrix/letsencrypt-certs:/etc/letsencrypt:rw,z \
docker.io/certbot/certbot:latest \
renew
ExecStartPost=/bin/systemctl restart --no-block nginx.service
```
#### Synapse and database
Finally, configure the Synapse server and PostgreSQL database.
The Synapse server requires a configuration and secrets keys to be generated. Follow the GitHub repositorys [README][20] file section to generate those.
Once these steps completed, add a systemd service using podman to run Synapse as a container:
```
- name: synapse.service
enabled: true
contents: |
[Unit]
Description=Run the synapse service.
After=podmanpod.service network-online.target
Wants=network-online.target
Requires=podmanpod.service
[Service]
ExecStart=/bin/podman run \
--name=synapse \
--pull=always \
--read-only \
--pod=matrix \
--rm \
-v /var/srv/matrix/synapse:/data:z \
docker.io/matrixdotorg/synapse:v1.24.0
ExecStop=/bin/podman rm --force --ignore synapse
[Install]
WantedBy=multi-user.target
```
Setting up the PostgreSQL database is very similar. You will also need to provide a _POSTGRES_PASSWORD_, in the repositorys secrets file and declare a systemd service (check [here][21] for all the details).
#### Setting the Fedora CoreOS host
FCCT provides a _storage_ directive which is useful for creating directories and adding files on the Fedora CoreOS host.
The following configuration makes sure that the configuration needed by each service is present under _/var/srv/matrix._ Each service has a dedicated directory. For example _/var/srv/matrix/nginx_ and _/var/srv/matrix/synapse_. These directories are mounted by podman as volumes when the containers are started.
```
storage:
directories:
- path: /var/srv/matrix
mode: 0700
- path: /var/srv/matrix/synapse/media_store
mode: 0777
- path: /var/srv/matrix/postgres
- path: /var/srv/matrix/letsencrypt-webroot
trees:
- local: synapse
path: /var/srv/matrix/synapse
- local: nginx
path: /var/srv/matrix/nginx
- local: nginx-http
path: /var/srv/matrix/nginx-http
- local: letsencrypt-certs
path: /var/srv/matrix/letsencrypt-certs
- local: well-known
path: /var/srv/matrix/well-known
- local: element-web
path: /var/srv/matrix/element-web
files:
- path: /etc/postgresql_synapse
contents:
local: postgresql_synapse
mode: 0700
```
#### Auto-updates
You are now ready to setup the most powerful part of Fedora CoreOS auto-updates. On Fedora CoreOS, the system is automatically updated and restarted approximately once every two weeks for each new Fedora CoreOS release. On startup, all containers will be updated to the latest version (because the _pull=always_ option is set). The containers are stateless and volume mounts are used for any data that needs to be persistent across reboots.
The PostgreSQL container is an exception. It can not be fully updated automatically because it requires manual intervention for major releases. However, it will still be updated with new patch releases to fix security issues and bugs as long as the specified version is supported ([approximately five years][22]). Be aware that Synapse might start requiring a newer version before support ends. Consequently, you should plan a manual update approximately once per year for new PostgreSQL releases. The steps to update PostgreSQL are documented in [this projects README][23].
To maximise availability and avoid service interruptions in the middle of the day, set an [update strategy in Zincatis configuration][24] to only allow reboots for updates during certain periods of time. For example, one might want to restrict reboots to week days between 2 AM and 4 AM UTC. Make sure to pick the correct time for your timezone. Fedora CoreOS uses the UTC timezone by default. Here is an example configuration snippet that you could append to your _config.yaml_:
```
[updates]
strategy = "periodic"
[[updates.periodic.window]]
days = [ "Mon", "Tue", "Wed", "Thu", "Fri" ]
start_time = "02:00"
length_minutes = 120
```
### Creating your own Matrix server by using the git repository
Some sections where lightly edited to make this article easier to read but you can find the full, unedited configuration in [this GitHub repository][16]. To host your own server from this configuration, fill in the secrets values and generate the full configuration with _fcct_ via the provided _Makefile_:
```
$ cp secrets.example secrets
${EDITOR} secrets
# Fill in values not marked as generated by synapse
```
Next, generate the [Synapse secrets][25] and include them in the secrets file. Finally, you can build the final configuration with _make_:
```
$ make
# This will generate the config.ign file
```
You are now ready to deploy your Matrix homeserver on Fedora CoreOS. Follow the instructions for your platform of choice [from the documentation][26] to proceed.
### Registering new users
Whats a service without users? Open registration was disabled by default to avoid issues. You can re-enable open registration in the Synapse configuration if you are up for it. Alternatively, even with open registration disabled, it is possible to add new users to your server via the command line:
```
$ sudo podman run --rm --tty --interactive \
--pod=matrix \
-v /var/srv/matrix/synapse:/data:z,ro \
--entrypoint register_new_matrix_user \
docker.io/matrixdotorg/synapse:latest \
-c /data/homeserver.yaml http://127.0.0.1:8008
```
### Conclusion
You are now ready to join the Matrix federated universe! Enjoy your quickly deployed and automatically updating Matrix server! Remember that auto-updates are made as safe as possible by the fact that if anything breaks, you can either rollback the system to the previous version or use the previous container image to work around any bugs while they are being fixed. Being able to quickly setup a system that will be kept updated and secure is the main advantage of the Fedora CoreOS model.
To go further, take a look at this other article that is taking advantage of Terraform to generate the configuration and directly deploy Fedora CoreOS on your platform of choice.
> [Deploy Fedora CoreOS servers with Terraform][27]
--------------------------------------------------------------------------------
via: https://fedoramagazine.org/deploy-your-own-matrix-server-on-fedora-coreos/
作者:[Clément VernaTimothée Ravier][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://fedoramagazine.org/author/cverna/https://fedoramagazine.org/author/siosm/
[b]: https://github.com/lujun9972
[1]: https://fedoramagazine.org/wp-content/uploads/2021/01/matrix-816x345.jpg
[2]: https://matrix.org/
[3]: https://wiki.mozilla.org/Matrix
[4]: https://community.kde.org/Matrix
[5]: https://matrix.org/faq/#what-does-federated-mean%3F
[6]: https://docs.fedoraproject.org/en-US/fedora-coreos/
[7]: https://fedoramagazine.org/getting-started-with-fedora-coreos/
[8]: https://github.com/matrix-org/synapse
[9]: https://www.postgresql.org/
[10]: https://www.nginx.com/
[11]: https://letsencrypt.org/
[12]: https://github.com/vector-im/element-web
[13]: https://podman.io/getting-started/
[14]: http://coreos.github.io/ignition/
[15]: https://coreos.github.io/fcct/getting-started/#container
[16]: https://github.com/travier/fedora-coreos-matrix
[17]: https://github.com/travier/fedora-coreos-matrix/tree/173cb59df81de531e9dc32798a6e4ff553cf6e79#how-to-use
[18]: https://en.wikipedia.org/wiki/Cross-site_scripting#Background
[19]: https://certbot.eff.org/docs/using.html#dns-plugins
[20]: https://github.com/travier/fedora-coreos-matrix/tree/173cb59df81de531e9dc32798a6e4ff553cf6e79#configuring-synapse
[21]: https://github.com/travier/fedora-coreos-matrix/blob/173cb59df81de531e9dc32798a6e4ff553cf6e79/config.yaml#L48
[22]: https://www.postgresql.org/support/versioning/
[23]: https://github.com/travier/fedora-coreos-matrix#postgresql-major-version-updates
[24]: https://coreos.github.io/zincati/usage/updates-strategy/#periodic-strategy
[25]: https://github.com/travier/fedora-coreos-matrix#configuring-synapse
[26]: https://docs.fedoraproject.org/en-US/fedora-coreos/getting-started/
[27]: https://fedoramagazine.org/deploy-fedora-coreos-with-terraform/

View File

@@ -1,409 +0,0 @@
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (Help safeguard your Linux server from attack with this REST API)
[#]: via: (https://opensource.com/article/21/1/crowdsec-rest-api)
[#]: author: (Philippe Humeau https://opensource.com/users/philippe-humeau)
Help safeguard your Linux server from attack with this REST API
======
CrowdSec's new architecture improves communication among components to
better protect systems against cybersecurity threats.
![Lock][1]
CrowdSec is an open source cybersecurity detection system meant to identify aggressive behaviors and prevent them from accessing systems. Its user-friendly design offers a low technical barrier of entry with a significant boost to security.
A modern behavior detection system written in Go, CrowdSec combines the philosophy of [Fail2ban][2] with Grok patterns and YAML grammar to analyze logs for a modern, decoupled approach for securing the cloud, containers, and virtual machine (VM) infrastructures. Once detected, a threat can be mitigated with bouncers (block, 403, captcha, and so on), and blocked internet protocol addresses (IPs) are shared among all users to improve everyone's security further.
December's official release of [CrowdSec v.1.0.][3][x][3] introduces several improvements, including a major architectural change: the introduction of a local REST API. This local API allows all components to communicate more efficiently to support more complex architectures while keeping things simple for single-machine users. It also makes it simpler to create bouncers (the remediation component) and renders them more resilient to upcoming changes, which limits maintenance time.
The CrowdSec architecture was deeply remodeled in the new 1.0 release.
![CrowdSec architecture][4]
(Priya James, [CC BY-SA 4.0][5])
All CrowdSec components (the agent reading logs, cscli for humans, and bouncers to deter the bad guys) can now communicate via a REST API instead of reading or writing directly in the database. With this new version, only the local API service will interact with the database (e.g., SQLite, PostgreSQL, or MySQL).
This article covers how to install and run CrowdSec on a Linux server:
* CrowdSec setup
* Testing detection capabilities
* Bouncer setup
* Observability
### Set up the environment
The machine I used for this test is a Debian 10 Buster t2.medium EC2.
To make it more relevant, install Nginx:
```
$ sudo apt-get update
$ sudo apt-get install nginx
```
Configure the security groups so that both secure shell (SSH) (tcp/22) and HTTP (tcp/80) can be reached from the outside world. This will be useful for simulating attacks later.
#### Install CrowdSec
Grab the latest version of CrowdSec:
```
`$ curl -s https://api.github.com/repos/crowdsecurity/crowdsec/releases/latest | grep browser_download_url| cut -d '"' -f 4  | wget -i -`
```
You can also download it from CrowdSec's [GitHub page][6].
Install it:
```
$ tar xvzf crowdsec-release.tgz
$ cd crowdsec-v1.0.0/
$ sudo ./wizard.sh -i
```
The wizard helps guide installation and configuration. And I have to say it's very helpful!
![CrowdSec Installation Wizard][7]
(Priya James, [CC BY-SA 4.0][5])
First, the wizard identifies services present on the machine:
![CrowdSec identifies services on the machine][8]
(Priya James, [CC BY-SA 4.0][5])
It allows you to choose which services to monitor. For this tutorial, go with the default option and monitor all three services: Nginx, SSHD, and the Linux system.
For each service, the wizard identifies the associated log files and asks you to confirm (use the defaults again):
![CrowdSec wizard identifies log files][9]
(Priya James, [CC BY-SA 4.0][5])
Once the services and associated log files have been identified correctly (which is crucial, as this is where CrowdSec will get its information), the wizard prompts you with suggested collections.
A [collection][10] is a set of configurations that aims to create a coherent ensemble to protect a technological stack. For example, the [crowdsecurity/sshd][11] collection contains a [parser for SSHD logs][12] and a [scenario to detect SSH bruteforce and SSH user enumeration][13].
The suggested collections are based on the services that you choose to protect.
![CrowdSec suggests collections][14]
(Priya James, [CC BY-SA 4.0][5])
The wizard's last step is to deploy [generic whitelists][15] to prevent banning private IP addresses. It also reminds you that CrowdSec will _detect_ malevolent IPs but _not ban_ any of them. You need a bouncer to block attacks. This is an essential thing to remember: _CrowdSec detects attacks; bouncers block them_.
![CrowdSec detects attacks][16]
(Priya James, [CC BY-SA 4.0][5])
Now that the initial setup is done, CrowdSec should be up and running.
![CrowdSec running][17]
(Priya James, [CC BY-SA 4.0][5])
### Detect attacks with CrowdSec
By installing CrowdSec, you should already have coverage for common internet background noise. Check it out!
#### Attack a web server with Wapiti
Simulate a web application vulnerability scan on your Nginx service using Wapiti, a web application vulnerability scanner. You need to do this from an external IP, and keep in mind that [private IPs are whitelisted by default][15]:
```
ATTACKER$ wapiti   -u <http://34.248.33.108/>
[*] Saving scan state, please wait...
 Note
========
This scan has been saved in the file
/home/admin/.wapiti/scans/34.248.33.108_folder_b753f4f6.db
...
```
On your freshly equipped machine, you can see the attacks in the logs:
![Seeing attacks in the logs][18]
(Priya James, [CC BY-SA 4.0][5])
My IP triggered different scenarios:
* [**crowdsecurity/http-path-traversal-probing**][19]: Detects path traversal probing attempt patterns in the `URI` or the `GET` parameters
* [**crowdsecurity/http-sqli-probing-detection**][20]: Detects obvious SQL injection probing attempt patterns in the `URI` or the `GET` parameters.
Bear in mind that the website you attacked in this example is an empty Nginx server. If this were a real website, the scanner would perform many other actions that would lead to more detections.
#### Check results with cscli
**[cscli][21]** is one of the main tools for interacting with the CrowdSec service, and one of its features is visualizing _active decisions_ and _past alerts_.
![cscli][22]
(Priya James, [CC BY-SA 4.0][5])
The `cscli decisions list` command displays active decisions at any time, while `cscli alerts list` shows past alerts (even if decisions are expired or the alert didn't lead to a decision).
You can also inspect a specific alert to get more details with `cscli alerts inspect -d <ID>` (using the ID displayed in the left-hand column of the alerts list).
![Inspect a specific alert][23]
(Priya James, [CC BY-SA 4.0][5])
cscli offers other features, but one to look at now is to find out which parsers and scenarios are installed in the default setup.
![Find installed parsers and scenarios][24]
(Priya James, [CC BY-SA 4.0][5])
### Observability
Observability (especially for software that might take defensive countermeasures) is always a key point for a security solution. Besides its "tail the logfile" capability, CrowdSec offers two ways to achieve this: Metabase dashboards and Prometheus metrics.
#### Metabase dashboard
cscli allows you to deploy a dashboard using Metabase and Docker. Begin by [installing Docker using its official documentation][25].
![Installing Docker][26]
(Priya James, [CC BY-SA 4.0][5])
If you're using an AWS EC2 instance, be sure to expose tcp/3000 to access your dashboard.
`cscli dashboard setup` enables you to deploy a new Metabase dashboard running on Docker with a random password.
![Metabase sign in][27]
(Priya James, [CC BY-SA 4.0][5])
![CrowdSec dashboard][28]
(Priya James, [CC BY-SA 4.0][5])
![CrowdSec dashboard timeline][29]
(Priya James, [CC BY-SA 4.0][5])
![CrowdSec dashboard attack sources][30]
(Priya James, [CC BY-SA 4.0][5])
#### Prometheus metrics
While some people love visual dashboards, others prefer other kinds of metrics. This is where CrowdSec's Prometheus integration comes into play.
One way to visualize these metrics is with `cscli metrics`.
![cscli metrics][31]
(Priya James, [CC BY-SA 4.0][5])
The `cscli metrics` command exposes only a subset of Prometheus metrics that are important for system administrators. You can find a detailed [description of the metrics in the documentation.][32] The metrics are split into sections:
* **Buckets:** How many buckets of each type were created, poured, or have overflowed since the daemon startup?
* **Acquisition:** How many lines or events were read from each of the specified sources, and were they parsed and/or poured into buckets later?
* **Parser:** How many lines/events were delivered to each parser, and did the parser succeed in processing the mentioned events?
* **Local API:** How many times was each route hit, and so on?
Viewing CrowdSec's Prometheus metrics via `cscli metrics` is convenient but doesn't do justice to Prometheus. It is out of scope for this article to deep dive into Prometheus, but these screenshots offer a quick look at what CrowdSec's Prometheus metrics look like in Grafana.
![CrowdSec's Prometheus metrics in Grafana][33]
(Priya James, [CC BY-SA 4.0][5])
![CrowdSec's Prometheus metrics in Grafana][34]
(Priya James, [CC BY-SA 4.0][5])
### Defend attacks with bouncers
CrowdSec's detection capabilities provide observability into what is going on. However, to protect yourself, you need to block attackers, which is where bouncers play a major part. Remember: CrowdSec detects, bouncers deter.
Bouncers work by querying CrowdSec's API to know when to block an IP. You can download bouncers directly from the [CrowdSec Hub][35].
![CrowdSec Hub][36]
(Priya James, [CC BY-SA 4.0][5])
For this example, use `cs-firewall-bouncer`. It directly bans any malevolent IP at the firewall level using iptables or nftables.
Note: If you used your IP to simulate attacks, _unban your IP_ before going further: 
```
`sudo cscli decisions delete -i X.X.X.X`
```
#### Install the bouncer
First, download the bouncer from the Hub:
```
$ wget <https://github.com/crowdsecurity/cs-firewall-bouncer/releases/download/v0.0.5/cs-firewall-bouncer.tgz>
$ tar xvzf cs-firewall-bouncer.tgz
$ cd cs-firewall-bouncer-v0.0.5/
```
Install the bouncer with a simple install script:
![Install Bouncer][37]
(Priya James, [CC BY-SA 4.0][5])
The install script will check if you have iptables or nftables installed and prompt you to install if not.
Bouncers communicate with CrowdSec via a REST API, so check that the bouncer is registered on the API.
![Check Bouncer Registration][38]
(Priya James, [CC BY-SA 4.0][5])
The last command (`sudo cscli bouncers list`) shows your newly installed bouncer.
#### Test the bouncer
**Warning:** Before going further, _ensure you have another IP available_ to access your machine and that you will not kick yourself out. Using your smartphone's internet connection will work.
Now that you have a bouncer to protect you, try the test again.
![Test the bouncer][39]
(Priya James, [CC BY-SA 4.0][5])
Try to access the server at the end of the scan:
```
ATTACKER$ curl --connect-timeout 1 <http://34.248.33.108/>
curl: (28) Connection timed out after 1001 milliseconds
```
See how it turns out from the defender's point of view.
![CrowdSec defender's point of view][40]
(Priya James, [CC BY-SA 4.0][5])
For the technically curious, `cs-firewall-bouncer` uses either nftables or iptables. Using nftables (used on Debian 10 by default) creates and maintains two tables named `crowdsec` and `crowdsec6` (for IPv4 and IPv6, respectively):
```
$ sudo nft list ruleset
table ip crowdsec {
        set crowdsec_blocklist {
                type ipv4_addr
                elements = { 3.22.63.25, 3.214.184.223,
                             3.235.62.151, 3.236.112.98,
                             13.66.209.11, 17.58.98.156, …
                        }
        }
        chain crowdsec_chain {
                type filter hook input priority 0; policy accept;
                ip saddr @crowdsec_blocklist drop
        }
}
table ip6 crowdsec6 {
        set crowdsec6_blocklist {
                type ipv6_addr
        }
        chain crowdsec6_chain {
                type filter hook input priority 0; policy accept;
                ip6 saddr @crowdsec6_blocklist drop
        }
}
```
You can change the firewall backend used by the bouncer in `/etc/crowdsec/cs-firewall-bouncer/cs-firewall-bouncer.yaml` by changing the mode from nftables to iptables (ipset is required for iptables mode).
### Get involved
Please share your feedback about the latest CrowdSec release. If you are interested in testing the software or would like to get in touch with the team, check the following links:
* [Download CrowdSec v.1.0][41][.x][3]
* [CrowdSec website][42]
* [GitHub repository][43]
* [Gitter][44]
* * *
_This article has been adapted from [Most advanced CrowdSec IPS v.1.0.x is out: how-to guide][45], originally published on GBHackers on Security._
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/1/crowdsec-rest-api
作者:[Philippe Humeau][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/philippe-humeau
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/security-lock-password.jpg?itok=KJMdkKum (Lock)
[2]: https://www.fail2ban.org/
[3]: https://github.com/crowdsecurity/crowdsec/releases/tag/v1.0.2
[4]: https://opensource.com/sites/default/files/uploads/crowdsec_newarchitecture.png (CrowdSec architecture)
[5]: https://creativecommons.org/licenses/by-sa/4.0/
[6]: https://github.com/crowdsecurity/crowdsec/releases/latest
[7]: https://opensource.com/sites/default/files/uploads/crowdsec_installationwizard.gif (CrowdSec Installation Wizard)
[8]: https://opensource.com/sites/default/files/uploads/crowdsec_servicestomonitor.png (CrowdSec identifies services on the machine)
[9]: https://opensource.com/sites/default/files/uploads/crowdsec_nginxlogfiles.png (CrowdSec wizard identifies log files)
[10]: https://doc.crowdsec.net/Crowdsec/v1/getting_started/concepts/#collections
[11]: https://hub.crowdsec.net/author/crowdsecurity/collections/sshd
[12]: https://hub.crowdsec.net/author/crowdsecurity/configurations/sshd-logs
[13]: https://hub.crowdsec.net/author/crowdsecurity/configurations/ssh-bf
[14]: https://opensource.com/sites/default/files/uploads/crowdsec_collections.png (CrowdSec suggests collections)
[15]: https://hub.crowdsec.net/author/crowdsecurity/configurations/whitelists
[16]: https://opensource.com/sites/default/files/uploads/crowdsec_detects.png (CrowdSec detects attacks)
[17]: https://opensource.com/sites/default/files/uploads/crowdsec_running.png (CrowdSec running)
[18]: https://opensource.com/sites/default/files/uploads/crowdsec_detectattack.png (Seeing attacks in the logs)
[19]: https://hub.crowdsec.net/author/crowdsecurity/configurations/http-path-traversal-probing
[20]: https://hub.crowdsec.net/author/crowdsecurity/configurations/http-sqli-probing
[21]: https://doc.crowdsec.net/Crowdsec/v1/user_guide/cscli/
[22]: https://opensource.com/sites/default/files/uploads/cscli.png (cscli)
[23]: https://opensource.com/sites/default/files/uploads/cscli-alerts-inspect.png (Inspect a specific alert)
[24]: https://opensource.com/sites/default/files/uploads/cscli_parsersscenarios.png (Find installed parsers and scenarios)
[25]: https://docs.docker.com/engine/install/debian/
[26]: https://opensource.com/sites/default/files/uploads/cscli_installdocker.png (Installing Docker)
[27]: https://opensource.com/sites/default/files/uploads/metabasesignin.png (Metabase sign in)
[28]: https://opensource.com/sites/default/files/uploads/crowdsec_maindashboard.png (CrowdSec dashboard)
[29]: https://opensource.com/sites/default/files/uploads/crowdsec_timeline.png (CrowdSec dashboard timeline)
[30]: https://opensource.com/sites/default/files/uploads/crowdsec_bysource_0.png (CrowdSec dashboard attack sources)
[31]: https://opensource.com/sites/default/files/uploads/cscli-metrics.png (cscli metrics)
[32]: https://doc.crowdsec.net/Crowdsec/v1/observability/prometheus/
[33]: https://opensource.com/sites/default/files/uploads/crowdsec_prometheus.png (CrowdSec's Prometheus metrics in Grafana)
[34]: https://opensource.com/sites/default/files/uploads/crowdsec_prometheus2.png (CrowdSec's Prometheus metrics in Grafana)
[35]: https://hub.crowdsec.net/browse/#bouncers
[36]: https://opensource.com/sites/default/files/uploads/crowdsec_hub.png (CrowdSec Hub)
[37]: https://opensource.com/sites/default/files/uploads/installbouncer.png (Install Bouncer)
[38]: https://opensource.com/sites/default/files/uploads/bouncerregistration.png (Check Bouncer Registration)
[39]: https://opensource.com/sites/default/files/uploads/crowdsectestbouncer.png (Test the bouncer)
[40]: https://opensource.com/sites/default/files/uploads/crowdsec_defender.png (CrowdSec defender's point of view)
[41]: https://github.com/crowdsecurity/crowdsec/releases/tag/v1.0.0
[42]: https://crowdsec.net/
[43]: https://github.com/crowdsecurity/crowdsec
[44]: https://gitter.im/crowdsec-project/community
[45]: https://gbhackers.com/crowdsec-ips-v-1-0-x/

View File

@@ -1,305 +0,0 @@
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (Firecracker: start a VM in less than a second)
[#]: via: (https://jvns.ca/blog/2021/01/23/firecracker--start-a-vm-in-less-than-a-second/)
[#]: author: (Julia Evans https://jvns.ca/)
Firecracker: start a VM in less than a second
======
Hello! I spent this whole past week figuring out how to use [Firecracker][1] and I really like it so far.
Initially when I read about Firecracker being released, I thought it was just a tool for cloud providers to use I knew that AWS Fargate and <https://fly.io> used it, but I didnt think that it was something that I could directly use myself.
But it turns out that Firecracker is relatively straightforward to use (or at least as straightforward as anything else thats for running VMs), the documentation and examples are pretty clear, you definitely dont need to be a cloud provider to use it, and as advertised, it starts VMs really fast!
So I wanted to write about using Firecracker from a more DIY “I just want to run some VMs” perspective.
Ill start out by talking about what Im using it for, and then Ill explain a few things I learned about it along the way.
### my goal: a game where every player gets their own virtual machine
Im working on a sort of game to help people learn command line tools by giving them a problem to solve and a virtual machine to solve it in, a little like a CTF. It still basically exists only on my computer, but Ive been working on it for a while.
Heres a screenshot of one of the puzzles Im working on right now. This one is about setting file extended attributes with `setfacl`.
<https://jvns.ca/images/read-me.png>
### why not use containers?
I wanted to use virtual machines and not containers for this project basically because I wanted to mimic a real production machine that the user has root access to I wanted folks to be able to set sysctls, use `nsenter`, make `iptables` rules, configure networking with `ip`, run `perf`, basically literally anything.
### the problem: starting a virtual machine is slow
I wanted people to be able to click “Start” on a puzzle and instantly launch a virtual machine. Originally I was launching a DigitalOcean VM every time, but they took about a minute to boot, I was getting really impatient waiting for them every time, and I didnt think it was an acceptable user experience for people to have to wait a minute.
I also tried using qemu, but for reasons I dont totally understand, starting a VM with qemu was also kind of slow it seemed to take at least maybe 20 seconds.
### Firecracker can start a VM in less than a second!
Firecracker says this about performance in their [specification][2]:
> It takes &lt;= 125 ms to go from receiving the Firecracker InstanceStart API call to the start of the Linux guest user-space /sbin/init process.
So far Ive been using Firecracker to start relatively large VMs Ubuntu VMs running systemd as an init system and it takes maybe 2-3 seconds for them to boot. I havent been measuring that closely because honestly 5 seconds is fast enough and I dont mind too much about an extra 200ms either way.
But enough background, lets talk about how to actually use Firecracker.
### heres a “hello world” script to start a Firecracker VM
I said at the beginning of this post that Firecracker is pretty straightforward to get started with. Heres how.
Firecrackers [getting started][3] instructions are really good (they just work!) but it was separated into a bunch of steps and I wanted to see everything you have to do together in 1 shell script. So I wrote a short shell script you can use to start a Firecracker VM, and some quick instructions for how to use it.
Running a script like this was the first thing I did when trying to wrap my head around Firecracker. Theres basically 3 steps:
**step 1**: Download Firecracker from their [releases page][4] and put it somewhere
**step 2**: Run this script as root (you might have to edit the last line with the path to the `firecracker` binary if its not in roots PATH)
I also put this script in a gist: [firecracker-hello-world.sh][5]. The IP addresses here are chosen pretty arbitrarily. Most the script is just writing a JSON file.
```
set -eu
# download a kernel and filesystem image
[ -e hello-vmlinux.bin ] || wget https://s3.amazonaws.com/spec.ccfc.min/img/hello/kernel/hello-vmlinux.bin
[ -e hello-rootfs.ext4 ] || wget -O hello-rootfs.ext4 https://github.com/firecracker-microvm/firecracker-demo/raw/master/xenial.rootfs.ext4
[ -e hello-id_rsa ] || wget -O hello-id_rsa https://raw.githubusercontent.com/firecracker-microvm/firecracker-demo/ec271b1e5ffc55bd0bf0632d5260e96ed54b5c0c/xenial.rootfs.id_rsa
TAP_DEV="fc-88-tap0"
# set up the kernel boot args
MASK_LONG="255.255.255.252"
MASK_SHORT="/30"
FC_IP="169.254.0.21"
TAP_IP="169.254.0.22"
FC_MAC="02:FC:00:00:00:05"
KERNEL_BOOT_ARGS="ro console=ttyS0 noapic reboot=k panic=1 pci=off nomodules random.trust_cpu=on"
KERNEL_BOOT_ARGS="${KERNEL_BOOT_ARGS} ip=${FC_IP}::${TAP_IP}:${MASK_LONG}::eth0:off"
# set up a tap network interface for the Firecracker VM to user
ip link del "$TAP_DEV" 2> /dev/null || true
ip tuntap add dev "$TAP_DEV" mode tap
sysctl -w net.ipv4.conf.${TAP_DEV}.proxy_arp=1 > /dev/null
sysctl -w net.ipv6.conf.${TAP_DEV}.disable_ipv6=1 > /dev/null
ip addr add "${TAP_IP}${MASK_SHORT}" dev "$TAP_DEV"
ip link set dev "$TAP_DEV" up
# make a configuration file
cat <<EOF > vmconfig.json
{
"boot-source": {
"kernel_image_path": "hello-vmlinux.bin",
"boot_args": "$KERNEL_BOOT_ARGS"
},
"drives": [
{
"drive_id": "rootfs",
"path_on_host": "hello-rootfs.ext4",
"is_root_device": true,
"is_read_only": false
}
],
"network-interfaces": [
{
"iface_id": "eth0",
"guest_mac": "$FC_MAC",
"host_dev_name": "$TAP_DEV"
}
],
"machine-config": {
"vcpu_count": 2,
"mem_size_mib": 1024,
"ht_enabled": false
}
}
EOF
# start firecracker
firecracker --no-api --config-file vmconfig.json
```
**step 3**: You have a VM running!
You can also SSH into the VM like this, with the SSH key that the script downloaded:
```
ssh -o StrictHostKeyChecking=false [email protected] -i hello-id_rsa
```
You might notice that if you run `ping 8.8.8.8` inside this VM, it doesnt work: its not able to connect to the outside internet. I think Im actually going to use a setup like this for my puzzles where people dont need to connect to the internet.
The networking commands and the rootfs image in this script are from the [firecracker-demo][6] repository which I found really helpful.
### how I put a Firecracker VM on the Docker bridge
I had a couple of problems with this “hello world” setup though:
* I wanted to be able to SSH to them from a Docker container (because I was running my games webserver in `docker-compose`)
* I wanted them to be able to connect to the outside internet
I struggled with trying to understand what a Linux bridge was and how it worked for about a day before figuring out how to get this to work. Heres a slight modification of the previous script [firecracker-hello-world-docker-bridge.sh][7] which runs a Firecracker VM on the Docker bridge
You can run it as root and SSH to the resulting VM like this (the IP is different because it has to be in the Docker subnet).
```
ssh -o StrictHostKeyChecking=false [email protected] -i hello-id_rsa
```
It basically just changes 2 things:
1. Theres an extra `sudo brctl addif docker0 $TAP_DEV` to add the VMs network interface to the Docker bridge
2. It changes the gateway in the kernel boot args to the Docker bridge network interfaces IP (172.17.0.1)
My guess is that most people probably wont want to use the Docker bridge, if you just want the VM to be able to connect to the outside internet I think the best way is to create a new bridge.
In my application Im actually using a bridge called `firecracker0` which is a docker-compose network I made. It feels a little sketchy to be using a bridge managed by Docker in this way but for now it works so Ill keep doing that unless I find a better way.
### how I built my own Firecracker images
This “hello world” example is all very well and good, but you might say ok, how do I build my own images?
Basically you have to do 2 things:
1. Make a Linux kernel. I wanted a 5.8 kernel so I used the instructions in the [firecracker docs on creating your own image][8] for compiling a Linux kernel and they worked. I was kind of intimidated by this because Id somehow never compiled a Linux kernel before, but I followed the instructions and it just worked the first time. I thought it would be super slow but it actually took less than 10 minutes to compile from scratch.
2. Make an `ext4` filesystem image with all the files you want in your VMs filesystem.
Heres how I put together my filesystem. Initially I tried downloading Ubuntus focal cloud image and extracting the root partition with `dd`, but I couldnt get it work.
Instead, I did what the Firecracker docs suggested and I built a Docker container and copied the contents of the container into a filesystem image.
Heres what the `Dockerfile` I used looked like approximately: (I havent tested this exact Dockerfile but I think it should work). The main things are that you have to install some kind of init system because the default `ubuntu:20.04` image doesnt come with one because you dont need one in a container. I also ran `unminimize` to restore some man pages because the container is for interactive use.
```
FROM ubuntu:20.04
RUN apt-get update
RUN apt-get install -y init openssh-server
RUN yes | unminimize
# copy over some SSH keys and install other programs I wanted
```
And heres the basic shell script Ive been using to create a filesystem image from the Docker container. I ran the whole thing as root, but technically you only have to run `mount` as root.
```
IMG_ID=$(docker build -q .)
CONTAINER_ID=$(docker run -td $IMG_ID /bin/bash)
MOUNTDIR=mnt
FS=mycontainer.ext4
mkdir $MOUNTDIR
qemu-img create -f raw $FS 800M
mkfs.ext4 $FS
mount $FS $MOUNTDIR
docker cp $CONTAINER_ID:/ $MOUNTDIR
umount $MOUNTDIR
```
Im still not quite sure how much Im going to like this approach of using Docker containers to create VM images it feels a bit weird to me but its been working fine so far.
I think most people who use Firecracker use a more lightweight init system than systemd and its definitely not necessary to use systemd but I think Im going to stick with systemd for now because I want it to feel mostly like a normal production Linux system and a lot of the production servers Ive used have used systemd.
Okay, thats all I have to say about creating images. Lets talk a bit more about configuring Firecracker.
### Firecracker supports either a socket interface or a configuration file
You can start a Firecracker VM 2 ways:
1. create a configuration file and run `firecracker --no-api --config-file vmconfig.json`
2. create an API socket and write instructions to the API socket (like they explain in their [getting started][3] instructions)
I really liked the configuration file approach for doing some initial experimentation because I found it easier to be able to see everything all in one place. But when integrating Firecracker with my actual application in real life, I found it easier to use the API.
### how I wrote a HTTP service that starts Firecracker VMs: use the Go SDK!
I wanted to have a little HTTP service that I could call from my Ruby on Rails server to start new VMs and stop them when I was done with them.
Heres what the interface looks like you give it a root image and a kernel and it returns an ID an the VMs IP address. All of the files paths are just local paths on my machine.
```
$ http post localhost:8080/create root_image_path=/images/base.ext4 kernel_path=/images/vmlinux-5.8
HTTP/1.1 200 OK
{
"id": "D248122A-1CCA-475C-856E-E3003A913F32",
"ip_address": "172.102.0.4"
}
```
and then heres what deleting a VM looks like (I might make this use the `DELETE` method later to make it more REST-y :) )
```
$ http post localhost:8080/delete id=D248122A-1CCA-475C-856E-E3003A913F32
HTTP/1.1 200 OK
```
At first I wasnt sure how I was going to use the Firecracker socket API to implement this interface, but then I discovered that theres a [Go SDK][9]! This made it way easier to generate the correct JSON, because there were a bunch of structs and the compiler would tell me if I made a typo in a field name.
I basically wrote all of my code so far by copying and modifying code from [firectl][10], a Go command line tool. The reason I wrote my own tool insted of just using `firectl` directly was that I wanted to have a HTTP API that could launch and stop lots of different VMs.
I found the `firectl` code and the Go SDK pretty easy to understand so I wont say too much more about it here.
If youre interested you can see [a gist with my current HTTP service for managing Firecracker VMs][11] which is a huge mess and pretty buggy and not intended for anyone but me to use. It does start VMs successfully though which is an important first step!!!
### DigitalOcean supports nested virtualization
Another question I had was: “ok, where am I going to run these Firecracker VMs in production?“. The funny thing about running a VM in the cloud is that cloud instances are _already_ VMs. Running a VM inside a VM is called “nested virtualization” and not all cloud providers support it for example AWS doesnt.
Right now Im using DigitalOcean and I was delighted to see that DigitalOcean does support nested virtualization even on their smallest droplets I tried running the “hello world” Firecracker script from above and it just worked!
I think GCP supports nested virtualization too but I havent tried it. The official Firecracker documentation suggests using a `metal` instance on AWS, probably because Firecracker is made by AWS.
I dont know what the performance implications of using nested virtualization are yet but I guess Ill find out!
### Firecracker only runs on Linux
I should say that Firecracker uses KVM so it only runs on Linux. I dont know if theres a way to start VMs in a similarly fast way on a Mac, maybe there is? Or maybe theres something special about KVM? I dont understand how KVM works.
### some open questions
A few things I still havent figured out:
* Right now Im not using `jailer`, another part of Firecracker that helps further isolate the Firecracker VM by adding some `seccomp-BPF` rules and other things. Maybe I should be! `firectl` uses `jailer` so it would be pretty easy to copy the code that does that.
* I still dont totally understand _why_ Firecracker is fast (or alternatively, why qemu is slow). This [LWN article][12] says that its because Firecracker emulates less devices than qemu does, but I dont know exactly which devices are the ones that are making qemu slow to start.
* will it be slow to use nested virtualization?
* I dont know if its possible to run graphical applications in Firecracker, it seems like it might not because its intended for servers, but maybe it is possible?
* Im not sure how many Firecracker VMs I can run at a time on my little $5/month DigitalOcean droplet, I need to do some of experiments.
--------------------------------------------------------------------------------
via: https://jvns.ca/blog/2021/01/23/firecracker--start-a-vm-in-less-than-a-second/
作者:[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://github.com/firecracker-microvm/firecracker/
[2]: https://github.com/firecracker-microvm/firecracker/blob/master/SPECIFICATION.md
[3]: https://github.com/firecracker-microvm/firecracker/blob/master/docs/getting-started.md#getting-the-firecracker-binary
[4]: https://github.com/firecracker-microvm/firecracker/releases
[5]: https://gist.github.com/jvns/c8470e75af67deec2e91ff1bd9883e53
[6]: https://github.com/firecracker-microvm/firecracker-demo/
[7]: https://gist.github.com/jvns/e13e6f498d26b584d8ab66651cdb04e0
[8]: https://github.com/firecracker-microvm/firecracker/blob/master/docs/rootfs-and-kernel-setup.md
[9]: https://github.com/firecracker-microvm/firecracker-go-sdk
[10]: https://github.com/firecracker-microvm/firectl/
[11]: https://gist.github.com/jvns/9b274f24cfa1db7abecd0d32483666a3
[12]: https://lwn.net/Articles/775736/

View File

@@ -1,217 +0,0 @@
[#]: subject: "How I programmed a virtual gift exchange"
[#]: via: "https://opensource.com/article/21/1/open-source-gift-exchange"
[#]: author: "Chris Hermansen https://opensource.com/users/clhermansen"
[#]: collector: "lkxed"
[#]: translator: " "
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
How I programmed a virtual gift exchange
======
A book club takes its annual gift exchange online with the help of HTML, CSS, and JavaScript.
![Package wrapped with brown paper and red bow][1]
Image by: Photo by [Jess Bailey][2] on [Unsplash][3]
Every year, my wife's book club has a book exchange during the holidays. Due to the need to maintain physical distance in 2020, I created an online gift exchange for them to use during a book club videoconference. Apparently, the virtual book exchange worked out (at least, I received kind compliments from the book club members), so I decided to share this simple little hack.
### How the book exchange usually works
In past years, the exchange has gone something like this:
1. Each person buys a book and wraps it up.
2. Everyone arrives at the host's home and puts the wrapped books in a pile.
3. Each person draws a number out of a hat, which establishes their turn.
4. The person who drew No. 1 selects a book from the pile and unwraps it. In turn, each subsequent person chooses to either take a wrapped book from the pile or to steal an unwrapped book from someone who has gone before.
5. When someone's book is stolen, they can either replace it with a wrapped book from the pile or steal another book (but not the one that was stolen from them) from someone else.
6. And so on… eventually, someone has to take the last unwrapped book to end the exchange.
### Designing the virtual book exchange
My first decision was which implementation platform to use for the book exchange. Because there would already be a browser open to host the videoconference, I decided to use HTML, CSS, and JavaScript.
Then it was design time. After some thinking, I decided to use rectangles to represent the book club members and the books. The books would be draggable, and when one was dropped on a member's rectangle, the book would unwrap (and stay unwrapped). I needed some "wrapping paper," so I used this source of [free-to-use images][4].
I took screenshots of the patterns I liked and used [GIMP][5] to scale the images to the right width and height.
I needed a way to handle draggable and droppable interactions; given that I've been using jQuery and jQuery UI for several years now, I decided to continue along that path.
For a while, I struggled with what a droppable element should do when something was dropped on it. Finally, I realized that all I needed to do was unwrap the dropped item (if it was still wrapped). I also spent some time fretting over how to lay stuff out until I realized that the easiest thing to do was just leave the elements floating.
Jumping to the results, here's a screenshot of the user interface at the beginning of the exchange:
![Virtual book exchange][6]
There are nine book club members: Wanda, Carlos, Bill, and so on. There are also nine fairly ugly wrapped parcels.
Let's say Wanda goes first and chooses the flower wrapping paper. The host clicks and drags that parcel to Wanda's name, and the parcel unwraps:
![Virtual book exchange][7]
Whoops! That title and author are a bit too long to fit on the book's "cover." Oh well, I'll fix that in the next version.
Carlos is next. He decides he really wants to read that book, so he steals it. Wanda then chooses the paisley pattern, and the screen looks like this:
![Virtual book exchange][8]
And so on until the exchange ends.
### The code
So what about the code? Here it is:
```
1  <!doctype html>
2  <html lang="en">
3  <head>
4    <meta charset="utf-8">
5    <title>Book Exchange</title>
6    <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/smoothness/jquery-ui.css">
7    <style>
8    .draggable {
9      float: left;
10      width: 90px;
11      height: 90px;
12      background: #ccc;
13      padding: 5px;
14      margin: 5px 5px 5px 0;
15    }
16    .droppable {
17      float: left;
18      width: 100px;
19      height: 125px;
20      background: #999;
21      color: #fff;
22      padding: 10px;
23      margin: 10px 10px 10px 0;
24    }
25    </style>
26    <script src="https://code.jquery.com/jquery-1.12.4.js"></script>
27    <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
28  </head>
29  <body>
30  <h1 style="color:#1a1aff;">Raffles Book Club Remote Gift Exchange</h1>
31  <h2 style="color:#aa0a0a;">The players, in random order, and the luxurious gifts, wrapped:</h2>
32   
33  <div>
34  <div id="wanda" class="droppable">Wanda</div>
35  <div id="carlos" class="droppable">Carlos</div>
36  <div id="bill" class="droppable">Bill</div>
37  <div id="arlette" class="droppable">Arlette</div>
38  <div id="joanne" class="droppable">Joanne</div>
39  <div id="aleks" class="droppable">Alekx</div>
40  <div id="ermintrude" class="droppable">Ermintrude</div>
41  <div id="walter" class="droppable">Walter</div>
42  <div id="hilary" class="droppable">Hilary</div>
43  </div>
44  <div>
45  <div id="bows" class="draggable" style="background-image: url('bows.png');"></div>
46  <div id="boxes" class="draggable" style="background-image: url('boxes.png');"></div>
47  <div id="circles" class="draggable" style="background-image: url('circles.png');"></div>
48  <div id="gerbers" class="draggable" style="background-image: url('gerbers.png');"></div>
49  <div id="hippie" class="draggable" style="background-image: url('hippie.png');"></div>
50  <div id="lattice" class="draggable" style="background-image: url('lattice.png');"></div>
51  <div id="nautical" class="draggable" style="background-image: url('nautical.png');"></div>
52  <div id="splodges" class="draggable" style="background-image: url('splodges.png');"></div>
53  <div id="ugly" class="draggable" style="background-image: url('ugly.png');"></div>
54  </div>
55   
56  <script>
57  var books = {
58      'bows': 'Untamed by Glennon Doyle',
59      'boxes': "The Heart's Invisible Furies by John Boyne",
60      'circles': 'The Great Halifax Explosion by John Bacon',
61      'gerbers': 'Homes: A Refugee Story by Abu Bakr al Rabeeah, Winnie Yeung',
62      'hippie': 'Before We Were Yours by Lisa Wingate',
63      'lattice': "Hamnet and Judith by Maggie O'Farrell",
64      'nautical': 'Shuggy Bain by Douglas Stewart',
65      'splodges': 'Magdalena by Wade Davis',
66      'ugly': 'Funny Boy by Shyam Selvadurai'
67  };
68  $( ".droppable" ).droppable({
69    drop: function(event, ui) {
70      var element = $(ui.draggable[0]);
71      var wrapping = element.attr('id');
72      /* alert( $(this).text() + " got " + wrapping); */
73      $(ui.draggable[0]).css("background-image","url(book_cover.png)");
74      $(ui.draggable[0]).text(books[wrapping]);
75    },
76    out: function() {
77      /* alert( $(this).text() + " lost it" ); */
78    }
79  });
80  $( ".draggable" ).draggable();
81  </script>
82   
83  </body>
84  </html>
```
### Breaking it down
Let's go over this code bit by bit.
* Lines 16: Upfront, I have the usual `HTML` boilerplate, HTML, `HEAD`, `META`, `TITLE` elements, followed by a link to the CSS for jQuery UI.
* Lines 725: I added two new style classes: `draggable` and `droppable`. These define the layout for the books (draggable) and the people (droppable). Note that, aside from defining the size, background color, padding, and margin, I established that these need to float left. This way, the layout adjusts to the browser window width in a reasonably acceptable form.
* Line 2627: With the CSS out of the way, it's time for the JavaScript libraries, first jQuery, then jQuery UI.
* Lines 2983: Now that the `HEAD` `element` is done, next is the `BODY`:
* Lines 3031: These couple of titles, `H1` and `H2`, let people know what they're doing here.
Lines 3343: A `DIV` to contain the people:
Lines 3442: The people are defined as `droppable` `DIV` elements and given `ID` fields corresponding to their names.
Lines 4454: A `DIV` to contain the books:
Lines 4553: The books are defined as `draggable` `DIV` elements. Each element is declared with a background image corresponding to the `wrapping` paper with no text between the `<div>` and `</div>`. The `ID` fields correspond to the wrapping paper.
Lines 5681: These contain JavaScript to make it all work.
* Lines 5767: This JavaScript object contains the book definitions. The keys ('bows', `'boxes'`, etc.) correspond to the `ID` fields of the book `DIV` elements. The values ('Untamed by Glennon Doyle', `"The Heart's Invisible Furies by John Boyne"`, etc.) are the book titles and authors.
Lines 6879: This JavaScript jQuery UI function defines the `droppable` functionality to be attached to HTML elements whose class is `drop`pable.
Lines 6975: When a `draggable` element is dropped onto a droppable element, the function drop is called.
Line 70: The element variable is assigned the draggable object that was dropped (this will be a `<div id="..." class="draggable"...></div>` element.
Line 71: The wrapping variable is assigned the value of the `ID` field in the draggable object.
Line 72: This line is commented `out`, but while I was learning and testing, calls to `alert()` were useful.
* Line 73: This reassigns the draggable object's background image to a bland image on which text can be read; part 1 of unwrapping is getting rid of the wrapping paper.
* Line 74: This sets the text of the draggable object to the title of the book, looked up in the book's object using the draggable object's ID; part 2 of the unwrapping is showing the book title and author.
Lines 7678: For a while, I thought I wanted something to happen when a draggable object was removed from a droppable object (e.g., when a club member stole a book), which would require using the out function in a droppable object. Eventually, I decided not to do anything. But, this could note that the book was stolen and make it "unstealable" for one turn; or it could show a status line that says something like: "Wanda's book Blah Blah by Joe Blogs was stolen, and she needs to choose another."
Line 80: This JavaScript jQuery UI function defines the draggable functionality to be attached to HTML elements whose class is draggable. In my case, the default behavior was all I needed.
That's it!
### A few last thoughts
Libraries like jQuery and jQuery UI are incredibly helpful when trying to do something complicated in JavaScript. Look at the `$().draggable()` and `$().droppable()` functions, for example:
```
$( ".draggable" ).draggable();
```
The `".draggable"` allows associating the `draggable()` function with any HTML element whose class is "draggable." The `draggable()` function comes with all sorts of useful behavior about picking, dragging, and releasing a draggable HTML element.
If you haven't spent much time with jQuery, I really like the book [jQuery in Action][9] by Bear Bibeault, Yehuda Katz, and Aurelio De Rosa. Similarly, [jQuery UI in Action][10] by TJ VanToll is a great help with the jQuery UI (where draggable and droppable come from).
Of course, there are many other JavaScript libraries, frameworks, and what-nots around to do good stuff in the user interface. I haven't really started to explore all that jQuery and jQuery UI offer, and I want to play around with the rest to see what can be done.
Image by: (Chris Hermansen, CC BY-SA 4.0)
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/1/open-source-gift-exchange
作者:[Chris Hermansen][a]
选题:[lkxed][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/clhermansen
[b]: https://github.com/lkxed
[1]: https://opensource.com/sites/default/files/lead-images/brown-package-red-bow.jpg
[2]: https://unsplash.com/@jessbaileydesigns?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText
[3]: https://unsplash.com/s/photos/package?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText
[4]: https://all-free-download.com/free-vector/patterns-creative-commons.html#google_vignette
[5]: https://opensource.com/tags/gimp
[6]: https://opensource.com/sites/default/files/uploads/bookexchangestart.png
[7]: https://opensource.com/sites/default/files/uploads/bookexchangeperson1.png
[8]: https://opensource.com/sites/default/files/uploads/bookexchangeperson2.png
[9]: https://www.manning.com/books/jquery-in-action-third-edition
[10]: https://www.manning.com/books/jquery-ui-in-action

View File

@@ -1,66 +0,0 @@
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (Schedule appointments with an open source alternative to Doodle)
[#]: via: (https://opensource.com/article/21/1/open-source-scheduler)
[#]: author: (Kevin Sonney https://opensource.com/users/ksonney)
Schedule appointments with an open source alternative to Doodle
======
Easy!Appointments is an open source appointment scheduler filled with
features to make planning your day easier.
![Working on a team, busy worklife][1]
In previous years, this annual series covered individual apps. This year, we are looking at all-in-one solutions in addition to strategies to help in 2021. Welcome to day 13 of 21 Days of Productivity in 2021.
Setting appointments with other people is difficult. Most of the time, we guess at a date and time and then start the "is this time bad for you? No, that time is bad for me, how about..." dance. It is easier with co-workers since you can see each others' calendars. You just have to find that magic spot that is good for almost everyone who needs to be on the call. However, for freelancers managing personal calendars, the dance is a routine part of setting up calls and meetings.
![Service and Provider set up screen][2]
Easy!Appointments (Kevin Sonney, [CC BY-SA 4.0][3])
This scheduling is a particular challenge for someone like me. Since I interview people for my weekly productivity podcast, finding a time that works for both of us can be extra challenging.
Finally, one of my guests said, "Hey, to get on my calendar, go to this URL, and pick a time that works for both of us."
This concept was, to be honest, a revelation. There is software (and services) out there that allows a person requesting the meeting to _pick_ a time that is good for both parties! No more back and forth trying to figure it out! It also means that I could give the person being interviewed control over their own availability.
![Appointment, Date, and Time settings][4]
Easy!Appointments (Kevin Sonney, [CC BY-SA 4.0][3])
There are several commercial and cloud-hosted solutions that provide this service. The best open source alternative I've used is [Easy!Appointments][5]. It is exceptionally easy to set up and has a handy WordPress plug-in that allows users to put the request form on a page or post.
Easy!Appointments is geared more towards a service organization, like a helpdesk or a handyman service, with the ability to add multiple people (aka Service Providers) and give them individual schedules. It also allows for various service types. While I only have it set up for one person (me) and one service (an interview), for a helpdesk, it might have four or five people and services like "Set up new laptop," "New hire setup," and "Set up new printer."
Easy!Appointments can also synchronize with Google Calendar on a per-person basis to automatically add or update any new appointments on their calendar. There are discussions in their issue tracker about support for syncing to additional backends. Easy!Appointments also supports multiple languages, time zones, and a whole host of other useful features.
![Final booking interface][6]
A final booking (Kevin Sonney, [CC BY-SA 4.0][3])
It has been freeing to be able to say, "You can book your interview on this web page," and spending less time negotiating when we are both available to talk. That gives both myself and the other person more time to do more productive things. Whether you are an individual, like me, or a service organization, Easy!Appointments is a big help when scheduling time with other people.
Need to keep your schedule straight? Learn how to do it using open source with these free...
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/1/open-source-scheduler
作者:[Kevin Sonney][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/ksonney
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/team_dev_email_chat_video_work_wfm_desk_520.png?itok=6YtME4Hj (Working on a team, busy worklife)
[2]: https://opensource.com/sites/default/files/day13-image1_1.png
[3]: https://creativecommons.org/licenses/by-sa/4.0/
[4]: https://opensource.com/sites/default/files/day13-image2_0.png
[5]: https://easyappointments.org/
[6]: https://opensource.com/sites/default/files/day13-image3_0.png

View File

@@ -1,107 +0,0 @@
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (Movim: An Open-Source Decentralized Social Platform Based on XMPP Network)
[#]: via: (https://itsfoss.com/movim/)
[#]: author: (Ankush Das https://itsfoss.com/author/ankush/)
Movim: An Open-Source Decentralized Social Platform Based on XMPP Network
======
_**Brief: Movim is an open-source decentralized social media platform that relies on XMPP network and can communicate with other applications using XMPP.**_
Weve already highlighted some [open-source alternatives to mainstream social media platforms][1]. In addition to those options available, I have come across another open-source social media platform that focuses on privacy and decentralization.
### Movim: Open-Source Web-based Social Platform
![][2]
Just like some other XMPP desktop clients, [Movim][3] is a web-based XMPP front-end to let you utilize it as a federated social media.
Since it relies on [XMPP network][4], you can interact with other users utilizing XMPP clients such as [Conversations][5] (for Android) and [Dino][6] (for Desktop).
In case you didnt know, XMPP is an open-standard for messaging.
So, Movim can act as your decentralized messaging app or a full-fledged social media platform giving you an all-in-one experience without relying on a centralized network.
It offers many features that can appeal to a wide variety of users. Let me briefly highlight most of the important ones.
![][7]
### Features of Movim
* Chatroom
* Ability to organize video conferences
* Publish articles/stories publicly to all federated network
* Tweak the privacy setting of your post
* Easily talk with other Movim users or XMPP users with different clients
* Automatically embed your links and images to your post
* Explore topics easily using hashtags
* Ability to follow a topic or publication
* Auto-save to draft when you type in a post
* Supports Markdown syntax to let you publish informative posts and start a publication on the network for free
* React to chat messages
* Supports GIFs and funny Stickers
* Edit or delete your messages
* Supports screen sharing
* Supports night mode
* Self-hosting option available
* Offers a free public instance as well
* Cross-platform web support
### Using Movim XMPP Client
![][8]
In addition to all the features listed above, it is also worth noting that you can also find a Movim mobile app on [F-Droid][9].
If you have an iOS device, you might have a hard time looking for a good XMPP client (Im not aware of any decent options). If you rule that out, you should not have any issues using it on your Android device.
For desktop, you can simply use Movims [public instance][10], sign up for an account, and use it on your favorite browser no matter which platform youre on.
You can also deploy your instance by using the Docker Compose script, the Debian package, or any other methods mentioned in their [GitHub page][11].
[Movim][3]
### Concluding Thoughts
While the idea of decentralized social media platforms is good, not everyone would prefer to use it because they probably do not have friends on it and the user experience is not the best out there.
That being said, XMPP clients like Movim are trying to make a federated social platform that a general consumer can easily use without any hiccups.
Just like it took a while for users to look for [WhatsApp alternatives][12], the craze for decentralized social media platform like Movim and [Mastodon][13] is a possibility in the near future as well.
If you like it, do consider making a donation to their project.
What do you think about Movim? Let me know your thoughts in the comments below.
--------------------------------------------------------------------------------
via: https://itsfoss.com/movim/
作者:[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://itsfoss.com/mainstream-social-media-alternaives/
[2]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/01/movim-dark-mode.jpg?resize=800%2C486&ssl=1
[3]: https://movim.eu/
[4]: https://xmpp.org/
[5]: https://conversations.im/
[6]: https://itsfoss.com/dino-xmpp-client/
[7]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/01/movim-discover.png?resize=800%2C466&ssl=1
[8]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/01/movim-eu.jpg?resize=800%2C464&ssl=1
[9]: https://f-droid.org/packages/com.movim.movim/
[10]: https://nl.movim.eu
[11]: https://github.com/movim/movim
[12]: https://itsfoss.com/private-whatsapp-alternatives/
[13]: https://itsfoss.com/mastodon-open-source-alternative-twitter/

View File

@@ -1,218 +0,0 @@
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (Build a programmable light display on Raspberry Pi)
[#]: via: (https://opensource.com/article/21/1/light-display-raspberry-pi)
[#]: author: (Darin London https://opensource.com/users/dmlond)
Build a programmable light display on Raspberry Pi
======
Celebrate the holidays or any special occasion with a DIY light display
using a Raspberry Pi, Python, and programmable LED lights.
![Lightbulb][1]
This past holiday season, I decided to add some extra joy to our house by setting up a DIY light display. I used a Raspberry Pi, a programmable light string, and Python.
<https://lh3.googleusercontent.com/pw/ACtC-3cPcJ_Lvnb-2jnZYydDOfAgovRmE5sPWoGDgw0nhHkfScmYKuebjHs7meF1-xGZZM6D92SpIQkygwg7zuM9IYi9b0AOOzwmEc1RaYzaAGcPp7YPptkntNKSGwoplQeyEcNwvqbCA6G1Ip8HVnqpLsEj=w640-h480-no?authuser=0>
You can set up your own light display for any occasion, thanks to the flexibility of the WS12911/2 (or NeoPixel) system, by following these directions.
### Prerequisites
You will need:
* 1 Raspberry Pi with headers and an Ethernet or WiFi connection. I used a Raspberry Pi Zero W with headers.
* 1 WS12811/2 light string. I used the [Alitove WS2811 Addressable LED Pixel Light 50][2], but many other types are available. Adafruit brands these as [NeoPixel][3].
* 1 [5v/10A AC-DC power supply for WS12811][4] if you use the Alitove. Other lights may come with a power supply.
* 1 Breadboard
* 2 Breadboard-to-Pi-header jumper wires. I used blue for the Pi GPIO pin 18 and black for the Pi ground.
* 1 74AHCT125 level converter chip to safely transmit Pi GPIO wire signals to 5v/10A power without feeding back to the Pi.
* 8 Breadboard-to-breadboard jumper wires or solid-core 24 AWG wires. I used red/orange for 5v power, black for ground, and yellow for data.
* 1 SD card with Raspberry Pi OS installed. I used [Raspberry Pi OS Lite][5] and set it up in a headless mode with SSH enabled.
### What are WS2811/2 programmable LEDs?
The [WS2811/2 class of programmable lights][6] integrates red, green, and blue LED lights with a driver chip into a tiny surface-mounted package controlled through a single wire.
![Programmable LED light][7]
(Darin London, [CC BY-SA 4.0][8])
Each light can be individually programmed using an RGB set of integers or hex equivalents. These lights can be packaged together into matrices, strings, and other form factors, and they can be programmatically accessed using a data structure that makes sense for the form factor. The light strings I use are addressed using a standard Python list. Adafruit has a great [tutorial on wiring and controlling your lights][9].
### Control NeoPixel LEDs with Python
Adafruit has created a full suite of Python libraries for most of the parts it sells. These are designed to work with [CircuitPython][10], Adafruit's port of Python designed for low-cost microcontroller boards. You do not need to install CircuitPython on the Raspberry Pi OS because the preinstalled Python 2 and Python 3 are compatible.
You will need to `pip3` to install libraries for Python 3. Install it with:
```
`sudo apt-get install python3-pip`
```
Then install the following libraries:
* [rpi_ws281x][11]
* [Adafruit-circuitpython-neopixel][12]
* [Adafruit-blinka][13]
Once these libraries and their dependencies are installed, you can write code like the following to program one or more lights wired to your Raspberry Pi using `sudo python3` (sudo is required):
```
import board
import neopixel
num_lights = 50
# program 50 lights with the default brightness 1.0, and autoWrite true
pixels = neopixel.NeoPixel(board.D18, num_lights)
# light 20 bright green
pixels[19] = (0,255,0)
# light all pixels red
pixels.fill((255.0,0))
# turn off neopixels
pixels.fill((0,0,0))
```
### Set up your lighting system
1. Install the SD card into the Raspberry Pi and secure it, the breadboard, and lights [where they need to be][14] (velcro works for the Pi and breadboard).
2. Install the 74AHCT125 level converter chip, light, power supply, and Pi according to this schematic:
![Wiring schematic][15]
([Kattni Rembor][16], [CC BY-SA 4.0][8])
3. String additional lights to the first light using their connectors. Note the total number of lights.
4. Plug the power supply into the wall.
5. Plug the Raspberry Pi power supply into the wall, and wait for it to boot.
 
![Lighting hardware wiring][17]
(Darin London, [CC BY-SA 4.0][8])
![Lighting hardware wiring][18]
(Darin London, [CC BY-SA 4.0][8])
![Lighting hardware wiring][19]
(Darin London, [CC BY-SA 4.0][8])
### Install the light controller and Flask web application
I wrote a Python application and library to interact with the lights and a Flask web application that runs on the Pi. See my [Raspberry Pi Neopixel Controller][20] GitHub repository for more information about the code.
#### The lib.neopixc library
The [`lib.neopixc` library][21] extends the `neopixel.NeoPixC` class to work with two 50-light Alitove light strands connected in serial, using a programmable list of RGB colors lists. It adds the following functions: 
* `set_color`: Takes a new list of lists of RGB colors
* `walk`: Walks through each light and sets them to the colors in order
* `rotate`: Pushes the last color in the list of lists to the beginning of the list of lists for blinking the lights
If you have a different number of lights, you will need to edit this library to change the `self._num_lights` value. Also, some lights require a different argument in the order constructor attribute. The Alitove is compatible with the default order attribute `neopixel.GRBW`.
#### The run_lights.py script
The [`run_lights.py` script][22] uses `lib.neopixc` to support a colors file and a state file to dynamically set how the lights behave at any time. The colors file is a JSON array of arrays of RGB (or RGBW) integers that is fed as the colors to the `lib.neopixc` object using its `set_colors` method. The state file can hold one of three words:
* `static`: Does not rotate the lights with each iteration of the while loop
* `blink`: Rotates the lights with each iteration of the main while loop
* `down`: Turns all the lights off
If the state file does not exist, the default state is `static`.
The script also has HUP and INT signal handlers, which will turn off the lights when those signals are received.
Note: Because the GPIO 18 pin requires sudo on the Raspberry Pi to work, the `run_lights.py` script must be run with sudo.
#### The neopixel_controller application
The `neopixel_controller` Flask application, in the neopix_controller directory of the github repository (see below), offers a front-end browser graphical user interface (GUI) to control the lights. My raspberry pi connects to my wifi, and is accessible at raspberrypi.local. To access the GUI in a browser, go to <http://raspberrypi.local:5000>. Alternatively, you can use ping to find the IP address of raspberrypi.local, and use it as the hostname, which is useful if you have multiple raspberry pi devices connected to your wifi.
![Flask app UI][23]
(Darin London, [CC BY-SA 4.0][8])
The current state and three front-end buttons use JavaScript to interact with a set of REST API endpoints presented by the Flask application:
* `/api/v1/state`: Returns the current state of the shared state file, which defaults to `static` if the state file does not exist
* `/api/v1/blink`: Sets the state file to blink
* `/api/v1/static`: Sets the state file to static
* `/api/v1/down`: Sets the state file to down
I wrote two scripts and corresponding JSON definition files that launch `run_lights.py` and the Flask application:
* `launch_christmas.sh`
* `launch_new_years.sh`
These can be launched from a command-line session (terminal or SSH) on the Pi after it is set up (they do not require sudo, but use sudo internally):
```
`./launch_christmas.sh`
```
You can turn off the lights and stop `run_lights.sh` and the Flask application by using `lights_down.sh`.
The code for the library and the flask application are in the [Raspberry Pi Neopixel Controller][20] GitHub repository.
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/1/light-display-raspberry-pi
作者:[Darin London][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/dmlond
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/lightbulb-idea-think-yearbook-lead.png?itok=5ZpCm0Jh (Lightbulb)
[2]: https://www.amazon.com/gp/product/B06XD72LYM
[3]: https://www.adafruit.com/category/168
[4]: https://www.amazon.com/gp/product/B01M0KLECZ
[5]: https://opensource.com/article/20/6/custom-raspberry-pi
[6]: https://learn.adafruit.com/adafruit-neopixel-uberguide
[7]: https://opensource.com/sites/default/files/uploads/led_1.jpg (Programmable LED light)
[8]: https://creativecommons.org/licenses/by-sa/4.0/
[9]: https://learn.adafruit.com/neopixels-on-raspberry-pi
[10]: https://circuitpython.org/
[11]: https://pypi.org/project/rpi-ws281x/
[12]: https://circuitpython.readthedocs.io/projects/neopixel/en/latest/api.html
[13]: https://pypi.org/project/Adafruit-Blinka/
[14]: https://gpiozero.readthedocs.io/en/stable/recipes.html#pin-numbering
[15]: https://opensource.com/sites/default/files/uploads/schematic.png (Wiring schematic)
[16]: https://learn.adafruit.com/assets/64121
[17]: https://opensource.com/sites/default/files/uploads/wiring.jpg (Lighting hardware wiring)
[18]: https://opensource.com/sites/default/files/uploads/wiring2.jpg (Lighting hardware wiring)
[19]: https://opensource.com/sites/default/files/uploads/wiring3.jpg (Lighting hardware wiring)
[20]: https://github.com/dmlond/raspberry_pi_neopixel
[21]: https://github.com/dmlond/raspberry_pi_neopixel/blob/main/lib/neopixc.py
[22]: https://github.com/dmlond/raspberry_pi_neopixel/blob/main/run_lights.py
[23]: https://opensource.com/sites/default/files/uploads/neopixelui.png (Flask app UI)

View File

@@ -1,164 +0,0 @@
[#]: subject: "Introduction to Thunderbird mail filters"
[#]: via: "https://fedoramagazine.org/introduction-to-thunderbird-mail-filters/"
[#]: author: "Richard England https://fedoramagazine.org/author/rlengland/"
[#]: collector: "lkxed"
[#]: translator: " "
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
Introduction to Thunderbird mail filters
======
![][1]
Everyone eventually runs into an inbox loaded with messages that they need to sort through. If you are like a lot of people, this is not a fast process. However, use of mail filters can make the task a little less tedious by letting Thunderbird pre-sort the messages into categories that reflect their source, priority, or usefulness. This article is an introduction to the creation of filters in Thunderbird.
Filters may be created for each email account you have created in Thunderbird. These are the accounts you see in the main Thunderbird folder pane shown at the left of the “Classic Layout”.
![][2]
There are two methods that can be used to create mail filters for your accounts. The first is based on the currently selected account and the second on the currently selected message. Both are discussed here.
### Message destination folder
Before filtering messages there has to be a destination for them. Create the destination by selecting a location to create a new folder. In this example the destination will be **Local Folders**shown in the accounts pane. Right click on **Local Folders** and select *New Folder…* from the menu.
![][3]
Enter the name of the new folder in the menu and select *Create Folder.* The mail to filter is coming from the New York Times so that is the name entered.
![][4]
### Filter creation based on the selected account
Select the *Inbox* for the account you wish to filter and select the toolbar menu item at *Tools > Message_Filters*.
![][5]
The *Message Filters* menu appears and is set to your pre-selected account as indicated at the top in the selection menu labelled *Filters for:*.
![][6]
Previously created filters, if any, are listed beneath the account name in the “*Filter Name”*column. To the right of this list are controls that let you modify the filters selected. These controls are activated when you select a filter. More on this later.
Start creating your filter as follows:
1. Verify the correct account has been pre-selected. It may be changed if necessary.
2. Select New… from the menu list at the right.
When you select *New* you will see the *Filter Rules*menu where you define your filter. Note that when using *New…* you have the option to copy an existing filter to use as a template or to simply duplicate the settings.
Filter rules are made up of three things, the “property” to be tested, the “test”, and the “value” to be tested against. Once the condition is met, the “action” is performed.
![][7]
Complete this filter as follows:
1. Enter an appropriate name in the textbox labelled Filter name:
2. Select the property From in the left drop down menu, if not set.
3. Leave the test set to contains.
4. Enter the value, in this case the email address of the sender.
Under the *Perform these actions:* section at the bottom, create an action rule to move the message and choose the destination.
1. Select Move Messages to from the left end of the action line.
2. Select Choose Folder… and select Local Folders > New York Times.
3. Select OK.
By default the **Apply filter when:** is set to *Manually Run* and *Getting New Mail:*. This means that when new mail appears in the Inbox for this account the filter will be applied and you may run it manually at any time, if necessary. There are other options available but they are too numerous to be discussed in this introduction. They are, however, for the most part self explanatory.
If more than one rule or action is to be created during the same session, the “+” to the right of each entry provides that option. Additional property, test, and value entries can be added. If more than one rule is created, make certain that the appropriate option for *Match all of the following* and *Match any of the following* is selected. In this example the choice does not matter since we are only setting one filter.
After selecting *OK,*the *Message Filters* menu is displayed again showing your newly created filter. Note that the menu items on the right side of the menu are now active for *Edit…* and *Delete.*
![][8]
Also notice the message *“Enabled filters are run automatically in the order shown below”*. If there are multiple filters the order is changed by selecting the one to be moved and using the *Move to Top, Move Up, Move Down,*or*Move to Bottom* buttons. The order can change the destination of your messages so consider the tests used in each filter carefully when deciding the order.
Since you have just created this filter you may wish to use the *Run Now* button to run your newly created filter on the Inbox shown to the left of the button.
### Filter creation based on a message
An alternative creation technique is to select a message from the message pane and use the *Create Filter From Message…* option from the menu bar.
In this example the filter will use two rules to select the messages: the email address and a text string in the Subject line of the email. Start as follows:
1. Select a message in the message page.
2. Select the filter options on the toolbar at Message > Create Filter From Message….
![][9]
The pre-selected message, highlighted in grey in the message pane above, determines the account used and *Create Filter From Message…* takes you directly to the *Filter Rules* menu.
![][10]
The property (*From*), test (*is*), and value (email) are pre-set for you as shown in the image above. Complete this filter as follows:
1. Enter an appropriate name in the textbox labelled Filter name:. COVID is the name in this case.
2. Check that the property is From.
3. Verify the test is set to is.
4. Confirm that the value for the email address is from the correct sender.
5. Select the “+” to the right of the From rule to create a new filter rule.
6. In the new rule, change the default property entry From to Subject using the pulldown menu.
7. Set the test to contains.
8. Enter the value text to be matched in the Email “Subject” line. In this case COVID.
Since we left the *Match all of the following* item checked, each message will be from the address chosen AND will have the text *COVID* in the email subject line.
Now use the action rule to choose the destination for the messages under the *Perform these actions:* section at the bottom:
1. Select Move Messages to from the left menu.
2. Select Choose Folder… and select Local Folders > COVID in Scotland. (This destination was created before this example was started. There was no magic here.)
3. Select OK.
*OK* will cause the *Message Filters* menu to appear, again, verifying that the new filter has been created.
### The Message Filters menu
All the message filters you create will appear in the *Message Filters* menu. Recall that the *Message Filters* is available in the menu bar at *Tools > Message Filters*.
Once you have created filters there are several options to manage them. To change a filter, select the filter in question and click on the *Edit* button. This will take you back to the *Filter Rules* menu for that filter. As mentioned earlier, you can change the order in which the rules are apply here using the *Move* buttons. Disable a filter by clicking on the check mark in the *Enabled* column.
![][11]
The *Run Now* button will execute the selected filter immediately. You may also run your filter from the menu bar using *Tools > Run Filters on Folder* or *Tools > Run Filters on Message*.
### Next step
This article hasnt covered every feature available for message filtering but hopefully it provides enough information for you to get started. Places for further investigation are the “property”, “test”, and “actions” in the *Filter menu* as well as the settings there for when your filter is to be run, *Archiving, After Sending,* and *Periodically*.
### References
Mozilla: [Organize][12][Your Messages][13][by Using Filters][14]
MozillaZine: [Message][15][Filters][16]
--------------------------------------------------------------------------------
via: https://fedoramagazine.org/introduction-to-thunderbird-mail-filters/
作者:[Richard England][a]
选题:[lkxed][b]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://fedoramagazine.org/author/rlengland/
[b]: https://github.com/lkxed
[1]: https://fedoramagazine.org/wp-content/uploads/2021/01/Tbird_mail_filters-1-816x345.jpg
[2]: https://fedoramagazine.org/wp-content/uploads/2021/01/Image_001-1024x613.png
[3]: https://fedoramagazine.org/wp-content/uploads/2021/01/Image_New_Folder.png
[4]: https://fedoramagazine.org/wp-content/uploads/2021/01/Folder_name-1.png
[5]: https://fedoramagazine.org/wp-content/uploads/2021/01/Image_002-2-1024x672.png
[6]: https://fedoramagazine.org/wp-content/uploads/2021/01/Image_Message_Filters-1.png
[7]: https://fedoramagazine.org/wp-content/uploads/2021/01/Filter_rules_1-1.png
[8]: https://fedoramagazine.org/wp-content/uploads/2021/01/Messsage_Filters_1st_entry.png
[9]: https://fedoramagazine.org/wp-content/uploads/2021/01/Create_by_messasge.png
[10]: https://fedoramagazine.org/wp-content/uploads/2021/01/Filter_rules_2-1.png
[11]: https://fedoramagazine.org/wp-content/uploads/2021/01/Message_Filters_2nd_entry.png
[12]: https://support.mozilla.org/en-US/kb/organize-your-messages-using-filters
[13]: https://support.mozilla.org/en-US/kb/organize-your-messages-using-filters
[14]: https://support.mozilla.org/en-US/kb/organize-your-messages-using-filters
[15]: http://kb.mozillazine.org/Filters_%28Thunderbird%29
[16]: http://kb.mozillazine.org/Filters_%28Thunderbird%29

View File

@@ -1,170 +0,0 @@
[#]: subject: "Interview with Shuah Khan, Kernel Maintainer & Linux Fellow"
[#]: via: "https://www.linux.com/news/interview-with-shuah-khan-kernel-maintainer-linux-fellow/"
[#]: author: "The Linux Foundation https://www.linuxfoundation.org/en/blog/interview-with-shuah-khan-kernel-maintainer-linux-fellow/"
[#]: collector: "lkxed"
[#]: translator: " "
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
Interview with Shuah Khan, Kernel Maintainer & Linux Fellow
======
Jason Perlow, Director of Project Insights and Editorial Content at the Linux Foundation, had an opportunity to speak with Shuah Khan about her experiences as a woman in the technology industry. She discusses how mentorship can improve the overall diversity and makeup of open source projects, why software maintainers are important for the health of open source projects such as the Linux kernel, and how language inclusivity and codes of conduct can improve relationships and communication between software maintainers and individual contributors.
**JP:** So, Shuah, I know you wear many different hats at the Linux Foundation. What do you call yourself around here these days?
**SK:** <laughs> Well, I primarily call myself a Kernel Maintainer & Linux Fellow. In addition to that, I focus on two areas that are important to the continued health and sustainability of the open source projects in the Linux ecosystem. The first one is bringing more women into the Kernel community, and additionally, I am leading the mentorship program efforts overall at the Linux Foundation. And in that role, in addition to the Linux Kernel Mentorship, we are looking at how the Linux Foundation mentorship program is working overall, how it is scaling. I make sure the [LFX Mentorship][1] platform scales and serves diverse mentees and mentors needs in this role.
The LF mentorships program includes several projects in the Linux kernel, LFN, HyperLedger, Open MainFrame, OpenHPC, and other technologies. [The Linux Foundations Mentorship Programs][2] are designed to help developers with the necessary skillsmany of whom are first-time open source contributorsexperiment, learn, and contribute effectively to open source communities.
The mentorship program has been successful in its mission to train new developers and make these talented pools of prospective employees trained by experts to employers. Several graduated mentees have found jobs. New developers have improved the quality and security of various open source projects, including the Linux kernel. Several Linux kernel bugs were fixed, a new subsystem mentor was added, and a new driver maintainer is now part of the Linux kernel community. My sincere thanks to all our mentors for volunteering to share their expertise.
**JP:** How long have you been working on the Kernel?
**SK:** Since 2010, or 2011, I got involved in the [Android Mainlining project][3]. My [first patch removed the Android pmem driver][4].
**JP:** Wow! Is there any particular subsystem that you specialize in?
**SK:** I am a self described generalist. I maintain the [kernel self-test][5] subsystem, the [USB over IP driver][6], [usbip tool][7], and the [cpupower][8] tool. I contributed to the media subsystem working on [Media Controller Device Allocator API][9] to resolve shared device resource management problems across device drivers from different subsystems.
**JP:** Hey, Ive [actually used the USB over IP driver][10] when I worked at Microsoft on Azure. And also, when Ive used AWS and Google Compute.
**SK:** Its a small niche driver used in cloud computing. Docker and other containers use that driver heavily. Thats how they provide remote access to USB devices on the server to export devices to be imported by other systems for use.
**JP:** I initially used it for IoT kinds of stuff in the embedded systems space. Were you the original lead developer on it, or was it one of those things you fell into because nobody else was maintaining it?
**SK:** Well, twofold. I was looking at USB over IP because I like that technology. it just so happened the driver was brought from the staging tree into the Mainline kernel, I volunteered at the time to maintain it. Over the last few years, we discovered some security issues with it, because it handles a lot of userspace data, so I had a lot of fun fixing all of those. <laugh>.
**JP:** What drew you into the Linux operating system, and what drew you into the kernel development community in the first place?
**SK:** Well, I have been doing kernel development for a very long time. I worked on the [LynxOS RTOS][11], a while back, and then HP/UX, when I was working at HP, after which I transitioned into  doing open source development — the [OpenHPI][12] project, to support HPs rack server hardware, and that allowed me to work much more closely with Linux on the back end. And at some point, I decided I wanted to work with the kernel and become part of the Linux kernel community. I started as an independent contributor.
**JP:** Maybe it just displays my own ignorance, but you are the first female, hardcore Linux kernel developer I have ever met. I mean, I had met female core OS developers before — such as when I was at Microsoft and IBM — but not for Linux. Why do you suppose we lack women and diversity in general when participating in open source and the technology industry overall?
**SK:** So Ill answer this question from my perspective, from what I have seen and experienced, over the years. You are right; you probably dont come across that many hardcore women Kernel developers. Ive been working professionally in this industry since the early 1990s, and on every project I have been involved with, I am usually the only woman sitting at the table. Some of it, I think, is culture and society. There are some roles that we are told are acceptable to women — even me, when I was thinking about going into engineering as a profession. Some of it has to do with where we are guided, as a natural path.
Theres a natural resistance to choosing certain professions that you have to overcome first within yourself and externally. This process is different for everybody based on their personality and their origin story. And once you go through the hurdle of getting your engineering degree and figuring out which industry you want to work in, there is a level of establishing credibility in those work environments you have to endure and persevere. Sometimes when I would walk into a room, I felt like people were looking at me and thinking, “why is she here?” You arent accepted right away, and you have to overcome that as well. You have to go in there and say, “I am here because I want to be here, and therefore, I belong here.” You have to have that mindset. Society sends you signals that “this profession is not for me” — and you have to be aware of that and resist it. I consider myself an engineer that happens to be a woman as opposed to a woman engineer.
**JP:** Are you from India, originally?
**SK:** Yes.
**JP:** Its funny; my wife really likes this [Netflix show about matchmaking in India][13]. Are you familiar with it?
**SK:** <laughs> Yes I enjoyed the series, and [A Suitable Girl][14] documentary film that follows three women as they navigate making decisions about their careers and family obligations.
**JP:** For many Americans, this is our first introduction to what home life is like for Indian people. But many of the women featured on this show are professionals, such as doctors, lawyers, and engineers. And they are very ambitious, but of course, the family tries to set them up in a marriage to find a husband for them that is compatible. As a result, you get to learn about the traditional values and roles they still want women to play there — while at the same time, many women are coming out of higher learning institutions in that country that are seeking technical careers.
**SK:** India is a very fascinatingly complex place. But generally speaking, in a global sense, having an environment at home where your parents tell you that you may choose any profession you want to choose is very encouraging. I was extremely fortunate to have parents like that. They never said to me that there was a role or a mold that I needed to fit into. They have always told me, “do what you want to do.” Which is different; I dont find that even here, in the US. Having that support system, beginning in the home to tell you, “you are open to whatever profession you want to choose,” is essential. Thats where a lot of the change has to come from.
**JP:** Women in technical and STEM professions are becoming much more prominent in other countries, such as China, Japan, and Korea. For some reason, in the US, I tend to see more women enter the medical profession than hard technology — and it might be a level of effort and perceived reward thing. You can spend eight years becoming a medical doctor or eight years becoming a scientist or an engineer, and it can be equally difficult, but the compensation at the end may not be the same. Its expensive to get an education, and it takes a long time and hard work, regardless of the professional discipline.
**SK:** I have also heard that women also like to enter professions where they can make a difference in the world — a human touch, if you will. So that may translate to them choosing careers where they can make a larger impact on people — and they may view careers in technology as not having those same attributes. Maybe when we think about attracting women to technology fields, we might have to promote technology aspects that make a difference. That may be changing now, such as the [LF Public Health][15] (LFPH) project we kicked off last year. And with [LF AI & Data Foundation][16], we are also making a difference in peoples lives, such as [detecting earthquakes][17] or [analyzing climate change][18]. If we were to promote projects such as these, we might draw more women in.
**JP:** So clearly, one of the areas of technology where you can make a difference is in open source, as the LF is hosting some very high-concept and existential types of projects such as [LF Energy][19], for example — I had no idea what was involved in it and what its goals were until I spoke to [Shuli Goodman][20] in-depth about it. With the mentorship program, I assume we need this to attract fresh talent — because as folks like us get older and retire, and they exit the field, we need new people to replace them. So I assume mentorship, for the Linux Foundation, is an investment in our own technologies, correct?
**SK:** Correct. Bringing in new developers into the fold is the primary purpose, of course — and at the same time, I view the LF as taking on mentorship provides that neutral, level playing field across the industry for all open source projects. Secondly, we offer a self-service platform, [LFX Mentorship][21], where anyone can come in and start their project. So when the COVID-19 pandemic began, we [expanded this program to help displaced people][22] — students, et cetera, and less visible projects. Not all projects typically get as much funding or attention as others do — such as a Kubernetes or  Linux kernel — among the COVID mentorship program projects we are funding. I am particularly proud of supporting a climate change-related project, [Using Machine Learning to Predict Deforestation][23].
The self-service approach allows us to fund and add new developers to projects where they are needed. The LF mentorships are remote work opportunities that are accessible to developers around the globe. We see people sign up for mentorship projects from places we havent seen before, such as Africa, and so on, thus creating a level playing field.
The other thing that we are trying to increase focus on is how do you get maintainers? Getting new developers is a starting point, but how do we get them to continue working on the projects they are mentored on? As you said, someday, you and I and others working on these things are going to retire, maybe five or ten years from now. This is a harder problem to solve than training and adding new developers to the project itself.
**JP:** And that is core to our [software supply chain security mission][24]. Its one thing to have this new, flashy project, and then all these developers say, “oh wow, this is cool, I want to join that,” but then, you have to have a certain number of people maintaining it for it to have long-term viability. As we learned in our [FOSS study with Harvard][25], there are components in the Linux operating system that are like this. Perhaps even modules within the kernel itself, I assume that maybe you might have only one or two people actively maintaining it for many years. And what happens if that person dies or can no longer work? What happens to that code? And if someone isnt familiar with that code, it might become abandoned. Thats a serious problem in open source right now, isnt it?
**SK:** Right. We have seen that with SSH and other security-critical areas. What if you dont have the bandwidth to fix it? Or the money to fix it? I ended up volunteering to maintain a tool for a similar reason when the maintainer could no longer contribute regularly. It is true; we have many drivers where maintainer bandwidth is an issue in the kernel. So the question is, how do we grow that talent pool?
**JP:** Do we need a job board or something? We need X number of maintainers. So should we say, “Hey, we know you want to join the kernel project as a contributor, and we have other people working on this thing, but we really need your help working on something else, and if you do a good job, we know tons of companies willing to hire developers just like you?”
**SK:** With the kernel, we are talking about organic growth; it is just like any other open source project. Its not a traditional hire and talent placement scenario. Organically they have to have credibility, and they have to acquire it through experience and relationships with people on those projects. We just talked about it at the previous [Linux Plumbers Conference][26], we do have areas where we really need maintainers, and the [MAINTAINERS][27] file does show areas where they need help.
To answer your question, its not one of those things where we can seek people to fill that role, like LinkedIn or one of the other job sites. It has to be an organic fulfillment of that role, so the mentorship program is essential in creating those relationships. It is the double-edged sword of open source; it is both the strength and weakness. People need to have an interest in becoming a maintainer and also a commitment to being one, long term.
**JP:** So, what do you see as the future of your mentorship and diversity efforts at the Linux Foundation? What are you particularly excited about that is forthcoming that you are working on?
**SK:** I view the Linux Foundation mentoring as a three-pronged approach to provide unstructured webinars, training courses, and structured mentoring programs. All of these efforts combine to advance a diverse, healthy, and vibrant open source community. So over the past several months, we have been morphing our speed mentorship style format into an expanded webinar format — the [LF Live Mentorship series][28]. This will have the function of growing our next level of expertise. As a complement to our traditional mentorship programs, these are webinars and courses that are an hour and a half long that we hold a few times a month that tackle specific technical areas in software development. So it might cover how to write great commit logs, for example, for your patches to be accepted, or how to find bugs in C code. Commit logs are one of those things that are important to code maintenance, so promoting good documentation is a beneficial thing. Webinars provide a way for experts short on time to share their knowledge with a few hours of time commitment and offer a self-paced learning opportunity to new developers.
Additionally, I have started the [Linux Kernel Mentorship forum][29] for developers and their mentors to connect and interact with others participating in the Linux Kernel Mentorship program and graduated mentees to mentor new developers. We kicked off [Linux Kernel mentorship Spring 2021][30] and are planning for Summer and Fall.
A big challenge is we are short on mentors to be able to scale the structured program. Solving the problem requires help from LF member companies and others to encourage their employees to mentor, “it takes a village,” they say.
**JP:** So this webinar series and the expanded mentorship program will help developers cultivate both hard and soft skills, then.
**SK:** Correct. The thing about doing webinars is that if we are talking about this from a diversity perspective, they might not have time for a full-length mentorship, typically like a three-month or six-month commitment. This might help them expand their resources for self-study. When we ask for developers feedback about what else they need to learn new skill sets, we hear that they dont have resources, dont have time to do self-study, and learn to become open source developers and software maintainers. This webinar series covers general open source software topics such as the Linux kernel and legal issues. It could also cover topics specific to other LF projects such as CNCF, Hyperledger, LF Networking, etc.
**JP:** Anything else we should know about the mentorship program in 2021?
**SK:** In my view,  attracting diversity and new people is two-fold. One of the things we are working on is inclusive language. Now, were not talking about curbing harsh words, although that is a component of what we are looking at. The English you and I use in North America isnt the same English used elsewhere. As an example, when we use North American-centric terms in our email communications, such as when a maintainer is communicating on a list with people from South Korea, something like “where the rubber meets the road” may not make sense to them at all. So we have to be aware of that.
**JP:** I know that you are serving on the [Linux kernel Code of Conduct Committee][31] and actively developing the handbook. When I first joined the Linux Foundation, I learned what the Community Managers do and our governance model. I didnt realize that we even needed to have codes of conduct for open source projects. I have been covering open source for 25 years, but I come out of the corporate world, such as IBM and Microsoft. Codes of Conduct are typically things that the Human Resources officer shows you during your initial onboarding, as part of reviewing your employee manual. You are expected to follow those rules as a condition of employment.
So why do we need Codes of Conduct in an open source project? Is it because these are people who are coming from all sorts of different backgrounds, companies, and ways of life, and may not have interacted in this form of organized and distributed project before? Or is it about personalities, people interacting with each other over long distance, and email, which creates situations that may arise due to that separation?
**SK:** Yes, I come out of the corporate world as well, and of course, we had to practice those codes of conduct in that setting. But conduct situations arise that you have to deal with in the corporate world. There are always interpersonal scenarios that can be difficult or challenging to work with — the corporate world isnt better than the open source world in that respect. It is just that all of that happens behind a closed setting.
But there is no accountability in the open source world because everyone participates out of their own free will. So on a small, traditional closed project, inside the corporate world, where you might have 20 people involved, you might get one or two people that could be difficult to work with. The same thing happens and is multiplied many times in the open source community, where you have hundreds of thousands of developers working across many different open source projects.
The biggest problem with these types of projects when you encounter situations such as this is dealing with participation in public forums. In the corporate world, this can be addressed in private. But on a public mailing list, if you are being put down or talked down to, it can be extremely humiliating.
These interactions are not always extreme cases; they could be simple as a maintainer or a lead developer providing negative feedback — so how do you give it? It has to be done constructively. And that is true for all of us.
**JP:** Anything else?
**SK:** In addition to bringing our learnings and applying this to the kernel project, I am also doing this on the [ELISA][32] project, where I chair the Technical Steering Committee, where I am bridging communication between experts from the kernel and the safety communities. To make sure we can use the kernel the best ways in safety-critical applications, in the automotive and medical industry, and so on. Many lessons can be learned in terms of connecting the dots, defining clearly what is essential to make Linux run effectively in these environments, in terms of dependability. How can we think more proactively instead of being engaged in fire-fighting in terms of security or kernel bugs? As a result of this, I am also working on any necessary kernel changes needed to support these safety-critical usage scenarios.
**JP:** Before we go, what are you passionate about besides all this software stuff? If you have any free time left, what else do you enjoy doing?
**SK:** I read a lot. COVID quarantine has given me plenty of opportunities to read. I like to go hiking, snowshoeing, and other outdoor activities. Living in Colorado gives me ample opportunities to be in nature. I also like backpacking — while I wasnt able to do it last year because of COVID — I like to take backpacking trips with my son. I also love to go to conferences and travel, so I am looking forward to doing that again as soon as we are able.
Talking about backpacking reminded me of the two-day, 22-mile backpacking trip during the summer of 2019 with my son. You can see me in the picture above at the end of the road, carrying a bearbox, sleeping bag, and hammock. It was worth injuring my foot and hurting in places I didnt even know I had.
**JP:** Awesome. I enjoyed talking to you today. So happy I finally got to meet you virtually.
The post [Interview with Shuah Khan, Kernel Maintainer & Linux Fellow][33] appeared first on [Linux Foundation][34].
--------------------------------------------------------------------------------
via: https://www.linux.com/news/interview-with-shuah-khan-kernel-maintainer-linux-fellow/
作者:[The Linux Foundation][a]
选题:[lkxed][b]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://www.linuxfoundation.org/en/blog/interview-with-shuah-khan-kernel-maintainer-linux-fellow/
[b]: https://github.com/lkxed
[1]: https://lfx.linuxfoundation.org/tools/mentorship/
[2]: https://linuxfoundation.org/about/diversity-inclusivity/mentorship/
[3]: https://elinux.org/Android_Mainlining_Project
[4]: https://lkml.org/lkml/2012/1/26/368
[5]: https://www.kernel.org/doc/html/v4.15/dev-tools/kselftest.html
[6]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/usb/usbip
[7]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/tools/usb/usbip
[8]: https://www.systutorials.com/docs/linux/man/1-cpupower/
[9]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/media/mc/mc-dev-allocator.c
[10]: https://www.linux-magazine.com/Issues/2018/208/Tutorial-USB-IP
[11]: https://en.wikipedia.org/wiki/LynxOS
[12]: http://www.openhpi.org/Developers
[13]: https://www.netflix.com/title/80244565
[14]: https://en.wikipedia.org/wiki/A_Suitable_Girl_(film)
[15]: https://www.lfph.io/
[16]: https://lfaidata.foundation/
[17]: https://openeew.com/
[18]: https://www.os-climate.org/
[19]: https://www.lfenergy.org/
[20]: https://www.linux.com/mailto:sgoodman@contractor.linuxfoundation.org
[21]: https://mentorship.lfx.linuxfoundation.org/
[22]: https://linuxfoundation.org/about/diversity-inclusivity/mentorship/
[23]: https://mentorship.lfx.linuxfoundation.org/project/926665ac-9b96-45aa-bb11-5d99096be870
[24]: https://www.linuxfoundation.org/en/blog/preventing-supply-chain-attacks-like-solarwinds/
[25]: https://www.linuxfoundation.org/en/press-release/new-open-source-contributor-report-from-linux-foundation-and-harvard-identifies-motivations-and-opportunities-for-improving-software-security/
[26]: https://www.linuxplumbersconf.org/
[27]: https://www.kernel.org/doc/linux/MAINTAINERS
[28]: https://events.linuxfoundation.org/lf-live-mentorship-series/
[29]: https://forum.linuxfoundation.org/categories/lfx-mentorship-linux-kernel
[30]: https://forum.linuxfoundation.org/discussion/858202/linux-kernel-mentorship-spring-projects-are-now-accepting-applications#latest
[31]: https://www.kernel.org/code-of-conduct.html
[32]: https://elisa.tech/
[33]: https://www.linuxfoundation.org/en/blog/interview-with-shuah-khan-kernel-maintainer-linux-fellow/
[34]: https://www.linuxfoundation.org/

View File

@@ -1,152 +0,0 @@
[#]: subject: "Start programming in Racket by writing a "guess the number" game"
[#]: via: "https://opensource.com/article/21/1/racket-guess-number"
[#]: author: "Cristiano L. Fontana https://opensource.com/users/cristianofontana"
[#]: collector: "lkxed"
[#]: translator: " "
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
Start programming in Racket by writing a "guess the number" game
======
Racket is a great way to learn a language from the Scheme and Lisp families.
![Person using a laptop][1]
I am a big advocate of learning multiple programming languages. That's mostly because I tend to get bored with the languages I use the most. It also teaches me new and interesting ways to approach programming.
Writing the same program in multiple languages is a good way to learn their differences and similarities. Previously, I wrote articles showing the same sample data plotting program written in [C & C++][2], JavaScript with [Node.js][3], and [Python and Octave][4].
This article is part of another series about writing a "guess the number" game in different programming languages. In this game, the computer picks a number between one and 100 and asks you to guess it. The program loops until you make a correct guess.
### Learning a new language
Venturing into a new language always feels awkward—I feel like I am losing time since it would be much quicker to use the tools I know and use all the time. Luckily, at the start, I am also very enthusiastic about learning something new, and this helps me overcome the initial pain. And once I learn a new perspective or a solution that I would never have thought of, things become interesting! Learning new languages also helps me backport new techniques to my old and tested tools.
When I start learning a new language, I usually look for a tutorial that introduces me to its [syntax][5]. Once I have a feeling for the syntax, I start working on a program I am familiar with and look for examples that will adapt to my needs.
### What is Racket?
[Racket][6] is a programming language in the [Scheme family][7], which is a dialect of [Lisp][8]. Lisp is also a family of languages, which can make it hard to decide which "dialect" to start with when you want to learn Lisp. All of the implementations have various degrees of compatibility, and this plethora of options might turn away newbies. I think that is a pity because these languages are really fun and stimulating!
Starting with Racket makes sense because it is very mature and versatile, and the community is very active. Since Racket is a Lisp-like language, a major characteristic is that it uses the [prefix notation][9] and a [lot of parentheses][10]. Functions and operators are applied to a list of operands by prefixing them:
```
(function-name operand operand ...)
(+ 2 3)
↳ Returns 5
(list 1 2 3 5)
↳ Returns a list containing 1, 2, 3, and 5
(define x 1)
↳ Defines a variable called x with value of 1
(define (f x y) (* x x))
↳ Defines a function called f with two parameters called x and y that returns their product.
```
This is basically all there is to know about Racket syntax; the rest is learning the functions from the [documentation][11], which is very thorough. There are other aspects of the syntax, like [keyword arguments][12] and [quoting][13], but you do not need them for this example.
Mastering Racket might be difficult, and its syntax might look weird (especially if you are used to languages like Python), but I find it very fun to use. A big bonus is Racket's programming environment, [DrRacket][14], which is very supportive, especially when you are getting started with the language.
The major Linux distributions offer packaged versions of Racket, so [installation][15] should be easy.
### Guess the number game in Racket
Here is a version of the "guess the number" program written in Racket:
```
#lang racket
(define (inquire-user number)
  (display "Insert a number: ")
  (define guess (string->number (read-line)))
  (cond [(> number guess) (displayln "Too low") (inquire-user number)]
        [(< number guess) (displayln "Too high") (inquire-user number)]
        [else (displayln "Correct!")]))
(displayln "Guess a number between 1 and 100")
(inquire-user (random 1 101))
```
Save this listing to a file called `guess.rkt` and run it:
```
$ racket guess.rkt
```
Here is some example output:
```
Guess a number between 1 and 100
Insert a number: 90
Too high
Insert a number: 50
Too high
Insert a number: 20
Too high
Insert a number: 10
Too low
Insert a number: 12
Too low
Insert a number: 13
Too low
Insert a number: 14
Too low
Insert a number: 15
Correct!
```
### Understanding the program
I'll go through the program line by line. The first line declares the language the listing is written into: `#lang racket`. This might seem strange, but Racket is very good at [writing interpreters][16] for new [domain-specific languages][17]. Do not panic, though! You can use Racket as it is because it is very rich in tools.
Now for the next line. `(define ...)` is used to declare new variables or functions. Here, it defines a new function called `inquire-user` that accepts the parameter `number`. The `number` parameter is the random number that the user will have to guess. The rest of the code inside the parentheses of the `define` procedure is the body of the `inquire-user` function. Notice that the function name contains a dash; this is Racket's idiomatic style for writing a long variable name.
This function recursively calls itself to repeat the question until the user guesses the right number. Note that I am not using loops; I feel that Racket programmers do not like loops and only use recursive functions. This approach is idiomatic to Racket, but if you prefer, [loops are an option][18].
The first step of the `inquire-user` function asks the user to insert a number by writing that string to the console. Then it defines a variable called `guess` that contains whatever the user entered. The [read-line function][19] returns the user input as a string. The string is then converted to a number with the [string->number function][20]. After the variable definition, the [cond function][21] accepts a series of conditions. If a condition is satisfied, it executes the code inside that condition. These conditions, `(> number guess)` and `(< number guess)`, are followed by two functions: a `displayln` that gives clues to the user and a `inquire-user` call. The function calls itself again when the user does not guess the right number. The `else` clause executes when the two conditions are not met, i.e., the user enters the correct number. The program's guts are this `inquire-user` function.
However, the function still needs to be called! First, the program asks the user to guess a number between 1 and 100, and then it calls the `inquire-user` function with a random number. The random number is generated with the [random function][22]. You need to inform the function that you want to generate a number between 1 and 100, but the `random` function generates integer numbers up to `max-1`, so I used 101.
### Try Racket
Learning new languages is fun! I am a big advocate of programming languages polyglotism because it brings new, interesting approaches and insights to programming. Racket is a great opportunity to start learning how to program with a Lisp-like language. I suggest you give it a try.
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/1/racket-guess-number
作者:[Cristiano L. Fontana][a]
选题:[lkxed][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/cristianofontana
[b]: https://github.com/lkxed
[1]: https://opensource.com/sites/default/files/lead-images/laptop_screen_desk_work_chat_text.png
[2]: https://opensource.com/article/20/2/c-data-science
[3]: https://opensource.com/article/20/6/data-science-nodejs
[4]: https://opensource.com/article/20/2/python-gnu-octave-data-science
[5]: https://en.wikipedia.org/wiki/Syntax_(programming_languages)
[6]: https://racket-lang.org/
[7]: https://en.wikipedia.org/wiki/Scheme_(programming_language)
[8]: https://en.wikipedia.org/wiki/Lisp_(programming_language)
[9]: https://en.wikipedia.org/wiki/Polish_notation
[10]: https://xkcd.com/297/
[11]: https://docs.racket-lang.org/
[12]: https://rosettacode.org/wiki/Named_parameters#Racket
[13]: https://docs.racket-lang.org/guide/quote.html
[14]: https://docs.racket-lang.org/drracket/
[15]: https://download.racket-lang.org/
[16]: https://docs.racket-lang.org/guide/hash-languages.html
[17]: https://en.wikipedia.org/wiki/Domain-specific_language
[18]: https://docs.racket-lang.org/heresy/conditionals.html
[19]: https://docs.racket-lang.org/reference/Byte_and_String_Input.html?q=read-line#%28def._%28%28quote._~23~25kernel%29._read-line%29%29
[20]: https://docs.racket-lang.org/reference/generic-numbers.html?q=string-%3Enumber#%28def._%28%28quote._~23~25kernel%29._string-~3enumber%29%29
[21]: https://docs.racket-lang.org/reference/if.html?q=cond#%28form._%28%28lib._racket%2Fprivate%2Fletstx-scheme..rkt%29._cond%29%29
[22]: https://docs.racket-lang.org/reference/generic-numbers.html?q=random#%28def._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._random%29%29

View File

@@ -1,73 +0,0 @@
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (How I de-clutter my digital workspace)
[#]: via: (https://opensource.com/article/21/1/declutter-workspace)
[#]: author: (Kevin Sonney https://opensource.com/users/ksonney)
How I de-clutter my digital workspace
======
Archive old email and other files to de-clutter your digital workspace.
![video editing dashboard][1]
In prior years, this annual series covered individual apps. This year, we are looking at all-in-one solutions in addition to strategies to help in 2021. Welcome to day 20 of 21 Days of Productivity in 2021.
I am a digital pack-rat. So many of us are. After all, who knows when we'll need that email our partner sent asking us to pick up milk on our way home from work in 2009?
The truth is, we don't need it. We _really_ don't. However, large cloud providers have given us so much storage space for cheap or for free that we don't even think about it anymore. When I can have unlimited documents, notes, to-do items, calendar appointments, and email, why _shouldn't_ I just keep everything?
![Marie Kondo indicating clearing email will bring you joy][2]
It really does. (Kevin Sonney, [CC BY-SA 4.0][3])
When dealing with physical items, like a notebook or a stack of documents, there comes a point where it is obvious we need to move it off our desks or out of our offices. We need to store it in some other place where we can get to it if we need to, but also know it will be safe. Eventually, that too fills up, and we are forced to clean out that storage as well.
Digital storage is really no different, only we're tempted to keep more things in it. If I have a note on my desk to pick something up on the way home, I'm going to throw it away when I'm done with it. That same note in my shared notebook with my wife is likely just to stay there. Maybe we'll re-use it, maybe we'll just let it sit there, taking up space.
This approach is the same as "hot" and "cold" storage. Hot storage is the most recent and relevant data that tends to be accessed frequently. Cold storage is for the archives we might need to refer to in the future and may have historical significance, but doesn't need to be accessed frequently.
Last year I took the time to export all of my emails from before 2019 and put them in an archive file. Then I deleted them. Why? For starters, I really didn't need any of it anymore. Sure it is nice to have the emails my spouse and I sent each other when we started dating, but they are not something I look at daily or even monthly. I could put them in cold storage, where they would be safe, and I could get them when I did want to look at them. The same for the emails and schedules for the conventions I had worked at before the pandemic. Do I need to have the schedule grid for my department at AnthroCon 2015 at my fingertips? NOPE.
### Archiving messages
The process of archiving messages will differ, depending on what email client you use, but the general idea is the same. In KMail, the email client from KDE, you can archive (and export, by nature of the archival process) a folder of messages by right-clicking on a folder and selecting **Archive Folder**. I also have KMail remove the messages after completing the archive.
![Archiving a directory of messages in KMail][4]
On the GNOME side of things, you can either export a folder of messages as an **mbox** file or you can use the **Save As** option to export it as an archive.
![Archive file of 2007-2019 email.][5]
8 Gb of mail (Kevin Sonney, [CC BY-SA 4.0][3])
If you're not on Linux, you might look into using the Thunderbird client. In Thunderbird, highlight the messages you want to archive (or press **Ctrl+A** to select all of them, and then right-click and select **Archive**.
![Archiving mail in Thunderbird][6]
### Cold storage
I have been managing my documents, notes, online to-do lists, and so on, by archiving the excess. I keep the most recent and relevant, and then I move the rest either into an archive file that does not live on my machine. Otherwise, if they no longer have any relevance, I just delete them altogether. That has made finding the relevant information much easier because there aren't loads of old things cluttering up my results.
It is important to take some time and de-clutter our digital workspaces the way we de-clutter our physical workspaces. Productivity isn't just getting things done, but also being able to find the right things we need to do them. Moving data into cold storage archives means we can rest easy knowing that it is safe if we need it and out of our way for the 99.9% of the time when we don't.
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/1/declutter-workspace
作者:[Kevin Sonney][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/ksonney
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/video_editing_folder_music_wave_play.png?itok=-J9rs-My (video editing dashboard)
[2]: https://opensource.com/sites/default/files/day20-image1.jpg
[3]: https://creativecommons.org/licenses/by-sa/4.0/
[4]: https://opensource.com/sites/default/files/kmail-archive.jpg (Archiving a directory of messages in KMail)
[5]: https://opensource.com/sites/default/files/day20-image2.png
[6]: https://opensource.com/sites/default/files/thunderbird-export.jpg (Archiving mail in Thunderbird)

View File

@@ -1,282 +0,0 @@
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (Best Single Board Computers for AI and Deep Learning Projects)
[#]: via: (https://itsfoss.com/best-sbc-for-ai/)
[#]: author: (Community https://itsfoss.com/author/itsfoss/)
Best Single Board Computers for AI and Deep Learning Projects
======
[Single-board computers][1] (SBC) are very popular with tinkerers and hobbyists alike, they offer a lot of functionality in a very small form factor. An SBC has the CPU, GPU, memory, IO ports, etc. on a small circuit board and users can add functionality by adding new devices to the [GPIO ports][2]. Some of the more popular SBCs include the [Raspberry Pi][3] and [Arduino][4] family of products.
However, there is an increasing demand for SBCs that can be used for edge compute applications like Artificial Intelligence (AI) or Deep Learning (DL) and there are quite a few. The list below consists of some of the best SBCs that have been developed for edge computing.
The list is in no particular order of ranking. Some links here are affiliate links. Please read our [affiliate policy][5].
### 1\. Nvidia Jetson Family
Nvidia has a great lineup of SBCs that cater to AI developers and hobbyists alike. Their line of “[Jetson Developer Kits][6]” are some of the most powerful and value for money SBCs available in the market. Below is a list of their offerings.
#### Nvidia Jetson Nano Developer Kit
![][7]
Starting at **$59**, the Jetson Nano is the cheapest SBC in the list and offers a good price to performance ratio. It can run multiple neural networks alongside other applications such as object detection, segmentation, speech processing and image classification.
The Jetson Nano is aimed towards AI enthusiasts, hobbyists and developers who want to do projects by implementing AI.
The Jetson Nano is being offered in two variants: 4 GB and 2 GB. The main differences between the two are, the price, RAM capacity and IO ports being offered. The 4 GB variant has been showcased in the image above.
**Key Specifications**
* **CPU:** Quad-core ARM A57 @ 1.43 GHz
* **GPU:** 128-core NVIDIA Maxwell
* **Memory:** 4 GB 64-bit LPDDR4 @ 25.6 GB/s or 2 GB 64-bit LPDDR4 @ 25.6 GB/s
* **Storage:** microSD card support
* **Display:** HDMI and Display Port or HDMI
Preview | Product | Price |
---|---|---|---
![NVIDIA Jetson Nano 2GB Developer Kit \(945-13541-0000-000\)][8] ![NVIDIA Jetson Nano 2GB Developer Kit \(945-13541-0000-000\)][8] | [NVIDIA Jetson Nano 2GB Developer Kit (945-13541-0000-000)][9] | $59.00[][10] | [Buy on Amazon][11]
#### Nvidia Jetson Xavier NX Developer Kit
![][12]
The Jetson Xavier NX is a step up from the Jetson Nano and is aimed more towards OEMs, start-ups and AI developers.
The Jetson Xavier NX is meant for applications that need more serious AI processing power that an entry level offering like the Jetson Nano simply cant deliver. The Jetson Xavier NX is being offered at **$386.99**.
**Key Specifications**
* **CPU:** 6-core NVIDIA Carmel ARM v8.2 64-bit CPU
* **GPU:** NVIDIA Volta architecture with 384 NVIDIA CUDA cores and 48 Tensor cores
* **DL Accelerator:** 2x NVDLA Engines
* **Vision Accelerator:** 7-Way VLIW Vision Processor
* **Memory:** 8 GB 128-bit LPDDR4x @ 51.2 GB/s
* **Storage:** microSD support
* **Display:** HDMI and Display Port
Preview | Product | Price |
---|---|---|---
![NVIDIA Jetson Xavier NX Developer Kit \(812674024318\)][13] ![NVIDIA Jetson Xavier NX Developer Kit \(812674024318\)][13] | [NVIDIA Jetson Xavier NX Developer Kit (812674024318)][14] | $386.89[][10] | [Buy on Amazon][15]
#### Nvidia Jetson AGX Xavier Developer Kit
![][16]
The Jetson AGX Xavier is the flagship product of the Jetson family, it is meant to be deployed in servers and AI robotics applications in industries such as manufacturing, retail, automobile, agriculture, etc.
Coming in at **$694.91**, the Jetson AGX Xavier is not meant for beginners, it is meant for developers who want top-tier edge compute performance at their disposal and for companies who want good scalability for their applications.
**Key Specifications**
* **CPU:** 8-core ARM v8.2 64-bit CPU
* **GPU:** 512-core Volta GPU with Tensor Cores
* **DL Accelerator:** 2x NVDLA Engines
* **Vision Accelerator:** 7-Way VLIW Vision Processor
* **Memory:** 32 GB 256-Bit LPDDR4x @ 137 GB/s
* **Storage:** 32 GB eMMC 5.1 and uSD/UFS Card Socket for storage expansion
* **Display:** HDMI 2.0
Preview | Product | Price |
---|---|---|---
![NVIDIA Jetson AGX Xavier Developer Kit \(32GB\)][17] ![NVIDIA Jetson AGX Xavier Developer Kit \(32GB\)][17] | [NVIDIA Jetson AGX Xavier Developer Kit (32GB)][18] | $694.91[][10] | [Buy on Amazon][19]
### 2\. ROCK Pi N10
![][20]
The ROCK Pi N10, developed by [Radxa][21] is the second cheapest offering in this list with its base variant coming in at **$99**, its range topping variant comes in at **$169**,
The ROCK Pi N10 is equipped with a NPU (Neural Processing Unit) that helps it in processing AI/ Deep Learning workloads with ease. It offers up to 3 TOPS (Tera Operations Per Second) of performance.
It is being offered in three variants namely, ROCK Pi N10 Model A, ROCK Pi N10 Model B, ROCK Pi N10 Model C, the only differences between these variants are the price, RAM and Storage capacities.
The ROCK Pi N10 is available for purchase through [Seeed Studio][22].
**Key Specifications**
* **CPU:** RK3399Pro with 2-core Cortex-A72 @ 1.8 GHz and 4-Core Cortex-A53 @ 1.4 GHz
* **GPU:** Mali T860MP4
* **NPU:** Supports 8bit/16bit computing with up to 3.0 TOPS computing power
* **Memory:** 4 GB/6 GB/8 GB 64-bit LPDDR3 @ 1866 Mb/s
* **Storage:** 16 GB/32 GB/64 GB eMMC
* **Display:** HDMI 2.0
### 3\. BeagleBone AI
![][23]
The BeagleBone AI is [BeagleBoard.org][24]s open source SBC is meant to bridge the gap between small SBCs and more powerful industrial computers. The hardware and software of the BeagleBoard are completely open source.
It is meant for use in the automation of homes, industries and other commercial use cases. It is priced at **~$110**, the price varies across dealers, for more info check [their website][25].
**Key Specifications**
* **CPU:** Texas Instrument AM5729 with Dual-core ARM Cortex-A15 @ 1.5GHz
* **Co-Processor:** 2 x Dual-core ARM Cortex-M4
* **DSP:** 2 x C66x floating-point VLIW
* **EVE:** 4 x Embedded Vision Engines
* **GPU:** PowerVR SGX544
* **RAM:** 1 GB
* **Storage:** 16 GB eMMC
* **Display:** microHDMI
Preview | Product | Price |
---|---|---|---
![BeagleBone AI][26] ![BeagleBone AI][26] | [BeagleBone AI][27] | $127.49[][10] | [Buy on Amazon][28]
### 4\. BeagleV
![][29]
The BeagleV is the latest launch in the list, it is an SBC that runs Linux out of the box and has a [RISC-V][30] CPU.
It is capable of running edge compute applications effortlessly, to know more about the BeagleV check [our coverage][31] of the launch.
The BeagleV will be getting two variants, a 4 GB RAM variant and an 8 GB RAM variant. Pricing starts at **$119** for the base model and **$149** for the 8 GB RAM model, it is up for pre-order through [their website][32].
**Key Specifications**
* **CPU:** RISC-V U74 2-Core @ 1.0GHz
* **DSP:** Vision DSP Tensilica-VP6
* **DL Accelerator:** NVDLA Engine 1-core
* **NPU:** Neural Network Engine
* **RAM:** 4 GB/8 GB (2 x 4 GB) LPDDR4 SDRAM
* **Storage:** microSD slot
* **Display:** HDMI 1.4
### 5\. HiKey970
![][33]
HiKey970 is [96 Boards][34] first SBC meant for edge compute applications and is the worlds first dedicated NPU AI platform.
The HiKey970 features an CPU, GPU and an NPU for accelerating AI performance, it can also be used for training and building DL (Deep Learning) models.
The HiKey970 is priced at **$299** and can be bought from their [official store][35].
**Key Specifications**
* **SoC:** HiSilicon Kirin 970
* **CPU:** ARM Cortex-A73 4-Core @ 2.36GHz and ARM Cortex-A53 4-Core @ 1.8GHz
* **GPU:** ARM Mali-G72 MP12
* **RAM:** 6 GB LPDDR4X @ 1866MHz
* **Storage:** 64 GB UFS 2.1 microSD
* **Display:** HDMI and 4 line MIPI/LCD port
### 6\. Google Coral Dev Board
![][36]
The Coral Dev Board is Googles first attempt at an SBC dedicated for edge computing. It is capable of performing high speed ML (Machine Learning) inferencing and has support for TensorFlow Lite and AutoML Vision Edge.
The board is priced at **$129.99** and is available through [Corals official website][37].
**Key Specifications**
* **CPU:** NXP i.MX 8M SoC (4-Core Cortex-A53, Cortex-M4F)
* **ML Accelerator**: Google Edge TPU coprocessor
* **GPU:** Integrated GC7000 Lite Graphics
* **RAM:** 1 GB LPDDR4
* **Storage:** 8 GB eMMC and microSD slot
* **Display:** HDMI 2.0a, 39-pin FFC connector for MIPI-DSI display (4-lane) and 24-pin FFC connector for MIPI-CSI2 camera (4-lane)
### 7\. Google Coral Dev Board Mini
![][38]
The Coral Dev Board Mini is the successor to the Coral Dev Board, it packs in more processing power into a smaller form factor and a lower price point of **$99.99**.
The Coral Dev Board Mini can be purchased from their [official web store][39].
**Key Specifications**
* **CPU:** MediaTek 8167s SoC (4-core Arm Cortex-A35)
* **ML Accelerator:** Google Edge TPU coprocessor
* **GPU:** IMG PowerVR GE8300
* **RAM:** 2 GB LPDDR3
* **Storage:** 8 GB eMMC
* **Display:** micro HDMI (1.4), 24-pin FFC connector for MIPI-CSI2 camera (4-lane) and 24-pin FFC connector for MIPI-DSI display (4-lane)
Preview | Product | Price |
---|---|---|---
![Google Coral Dev Board Mini][40] ![Google Coral Dev Board Mini][40] | [Google Coral Dev Board Mini][41] | $99.99[][10] | [Buy on Amazon][42]
### Closing Thoughts
There is an SBC available in every price range for edge compute applications. Some are just basic, like the Nvidia Jetson Nano or the BeagleBone AI and some are performance oriented models like the BeagleV and Nvidia Jetson AGX Xavier.
If you are looking for something more universal you can check [our article on Raspberry Pi alternatives][1] that could help you in finding a suitable SBC for your use case.
If I missed any SBC dedicated for edge compute, feel free to let me know in the comments below.
_**Author info: Sourav Rudra is a FOSS Enthusiast with love for Gaming Rigs/Workstation building.**_
--------------------------------------------------------------------------------
via: https://itsfoss.com/best-sbc-for-ai/
作者:[Community][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/itsfoss/
[b]: https://github.com/lujun9972
[1]: https://itsfoss.com/raspberry-pi-alternatives/
[2]: https://en.wikipedia.org/wiki/General-purpose_input/output
[3]: https://www.raspberrypi.org/products/
[4]: https://www.arduino.cc/en/main/products
[5]: https://itsfoss.com/affiliate-policy/
[6]: https://developer.nvidia.com/embedded/jetson-developer-kits
[7]: https://i0.wp.com/news.itsfoss.com/wp-content/uploads/2021/01/Nvidia-Jetson-Nano.png?ssl=1
[8]: https://i1.wp.com/m.media-amazon.com/images/I/310YWrfdnTL._SL160_.jpg?ssl=1
[9]: https://www.amazon.com/dp/B08J157LHH?tag=chmod7mediate-20&linkCode=osi&th=1&psc=1 (NVIDIA Jetson Nano 2GB Developer Kit (945-13541-0000-000))
[10]: https://www.amazon.com/gp/prime/?tag=chmod7mediate-20 (Amazon Prime)
[11]: https://www.amazon.com/dp/B08J157LHH?tag=chmod7mediate-20&linkCode=osi&th=1&psc=1 (Buy on Amazon)
[12]: https://i1.wp.com/news.itsfoss.com/wp-content/uploads/2021/01/Nvidia-Jetson-Xavier-NX.png?ssl=1
[13]: https://i1.wp.com/m.media-amazon.com/images/I/31B9xMmCvwL._SL160_.jpg?ssl=1
[14]: https://www.amazon.com/dp/B086874Q5R?tag=chmod7mediate-20&linkCode=ogi&th=1&psc=1 (NVIDIA Jetson Xavier NX Developer Kit (812674024318))
[15]: https://www.amazon.com/dp/B086874Q5R?tag=chmod7mediate-20&linkCode=ogi&th=1&psc=1 (Buy on Amazon)
[16]: https://i1.wp.com/news.itsfoss.com/wp-content/uploads/2021/01/Nvidia-Jetson-AGX-Xavier-.png?ssl=1
[17]: https://i1.wp.com/m.media-amazon.com/images/I/41tO5hw4zHL._SL160_.jpg?ssl=1
[18]: https://www.amazon.com/dp/B083ZL3X5B?tag=chmod7mediate-20&linkCode=ogi&th=1&psc=1 (NVIDIA Jetson AGX Xavier Developer Kit (32GB))
[19]: https://www.amazon.com/dp/B083ZL3X5B?tag=chmod7mediate-20&linkCode=ogi&th=1&psc=1 (Buy on Amazon)
[20]: https://i2.wp.com/news.itsfoss.com/wp-content/uploads/2021/01/ROCK-Pi-N10.png?ssl=1
[21]: https://wiki.radxa.com/Home
[22]: https://www.seeedstudio.com/ROCK-Pi-4-c-1323.html?cat=1343
[23]: https://i1.wp.com/news.itsfoss.com/wp-content/uploads/2021/01/Beagle-AI.png?ssl=1
[24]: https://beagleboard.org/
[25]: https://beagleboard.org/ai
[26]: https://i2.wp.com/m.media-amazon.com/images/I/41K+htPCUHL._SL160_.jpg?ssl=1
[27]: https://www.amazon.com/dp/B07YR1RV64?tag=chmod7mediate-20&linkCode=ogi&th=1&psc=1 (BeagleBone AI)
[28]: https://www.amazon.com/dp/B07YR1RV64?tag=chmod7mediate-20&linkCode=ogi&th=1&psc=1 (Buy on Amazon)
[29]: https://i2.wp.com/news.itsfoss.com/wp-content/uploads/2021/01/BeagleV.png?ssl=1
[30]: https://en.wikipedia.org/wiki/RISC-V
[31]: https://news.itsfoss.com/beaglev-announcement/
[32]: https://beaglev.seeed.cc/
[33]: https://i0.wp.com/news.itsfoss.com/wp-content/uploads/2021/01/HiKey970.png?ssl=1
[34]: https://www.96boards.org/
[35]: https://www.96boards.org/product/hikey970/
[36]: https://i1.wp.com/news.itsfoss.com/wp-content/uploads/2021/01/Google-Coral-Dev-Board.png?ssl=1
[37]: https://coral.ai/products/dev-board/
[38]: https://i0.wp.com/news.itsfoss.com/wp-content/uploads/2021/01/Google-Coral-Dev-Board-Mini.png?ssl=1
[39]: https://coral.ai/products/dev-board-mini
[40]: https://i0.wp.com/m.media-amazon.com/images/I/41g5c6IwLmL._SL160_.jpg?ssl=1
[41]: https://www.amazon.com/dp/B08QLXKJB7?tag=chmod7mediate-20&linkCode=ogi&th=1&psc=1 (Google Coral Dev Board Mini)
[42]: https://www.amazon.com/dp/B08QLXKJB7?tag=chmod7mediate-20&linkCode=ogi&th=1&psc=1 (Buy on Amazon)

View File

@@ -1,220 +0,0 @@
[#]: subject: "Astrophotography with Fedora Astronomy Lab: setting up"
[#]: via: "https://fedoramagazine.org/astrophotography-with-fedora-astronomy-lab-setting-up/"
[#]: author: "Geoffrey Marr https://fedoramagazine.org/author/coremodule/"
[#]: collector: "lkxed"
[#]: translator: " "
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
Astrophotography with Fedora Astronomy Lab: setting up
======
![][1]
Photo by Geoffrey Marr
You love astrophotography. You love Fedora Linux. What if you could do the former using the latter? Capturing stunning and awe-inspiring astrophotographs, processing them, and editing them for printing or sharing online using Fedora is absolutely possible! This tutorial guides you through the process of setting up a computer-guided telescope mount, guide cameras, imaging cameras, and other pieces of equipment. A future article will cover capturing and processing data into pleasing images. Please note that while this article is written with certain aspects of the astrophotography process included or omitted based off my own equipment, you can custom-tailor it to fit your own equipment and experience. Lets capture some photons!
![][2]
### Installing Fedora Astronomy Lab
This tutorial focuses on [Fedora Astronomy Lab][3], so it only makes sense that the first thing we should do is get it installed. But first, a quick introduction: based on the KDE Plasma desktop, Fedora Astronomy Lab includes many pieces of open source software to aid astronomers in planning observations, capturing data, processing images, and controlling astronomical equipment.
Download Fedora Astronomy Lab from the [Fedora Labs website][4]. You will need a USB flash-drive with at least eight GB of storage. Once you have downloaded the ISO image, use [Fedora Media Writer][5] to [write the image to your USB flash-drive.][6] After this is done, [boot from the USB drive][7] you just flashed and [install Fedora Astronomy Lab to your hard drive.][8] While you can use Fedora Astronomy Lab in a live-environment right from the flash drive, you should install to the hard drive to prevent bottlenecks when processing large amounts of astronomical data.
### Configuring your installation
Before you can go capturing the heavens, you need to do some minor setup in Fedora Astronomy Lab.
First of all, you need to add your user to the *dialout* group so that you can access certain pieces of astronomical equipment from within the guiding software. Do that by opening the terminal (Konsole) and running this command (replacing *user* with your username):
My personal setup includes a guide camera (QHY5 series, also known as Orion Starshoot) that does not have a driver in the mainline Fedora repositories. To enable it, ypu need to install the [qhyccd SDK][9]. (*Note that this package is not officially supported by Fedora. Use it at your own risk.)* At the time of writing, I chose to use the latest stable release, 20.08.26. Once you download the Linux 64-bit version of the SDK, to extract it:
```
tar zxvf sdk_linux64_20.08.26.tgz
```
Now change into the directory you just extracted, change the permissions of the *install.sh* file to give you execute privileges, and run the *install.sh*:
```
cd sdk_linux64_20.08.26
chmod +x install.sh
sudo ./install.sh
```
Now its time to install the qhyccd INDI driver. INDI is an open source software library used to control astronomical equipment. Unfortunately, the driver is unavailable in the mainline Fedora repositories, but it is in a Copr repository. (*Note: Copr is not officially supported by Fedora infrastructure. Use packages at your own risk.)* If you prefer to have the newest (and perhaps unstable!) pieces of astronomy software, you can also enable the “bleeding” repositories at this time by following [this guide][10]. For this tutorial, you are only going to enable one repo:
```
sudo dnf copr enable xsnrg/indi-3rdparty-bleeding
```
Install the driver by running the following command:
```
sudo dnf install indi-qhy
```
Finally, update all of your system packages:
To recap what you accomplished in this sectio: you added your user to the *dialout* group, downloaded and installed the qhyccd driver, enabled the *indi-3rdparty-bleeding* copr, installed the qhyccd-INDI driver with dnf, and updated your system.
### Connecting your equipment
This is the time to connect all your equipment to your computer. Most astronomical equipment will connect via USB, and its really as easy as plugging each device into your computers USB ports. If you have a lot of equipment (mount, imaging camera, guide camera, focuser, filter wheel, etc), you should use an external powered-USB hub to make sure that all connected devices have adequate power. Once you have everything plugged in, run the following command to ensure that the system recognizes your equipment:
```
lsusb
```
You should see output similar to (but not the same as) the output here:
![][11]
You see in the output that the system recognizes the telescope mount (a SkyWatcher EQM-35 Pro) as *Prolific Technology, Inc. PL2303 Serial Port*, the imaging camera (a Sony a6000) as *Sony Corp. ILCE-6000*, and the guide camera (an Orion Starshoot, aka QHY5) as *Van Ouijen Technische Informatica*. Now that you have made sure your system recognizes your equipment, its time to open your desktop planetarium and telescope controller, KStars!
### Setting up KStars
Its time to open [KStars][12], which is a desktop planetarium and also includes the Ekos telescope control software. The first time you open KStars, you will see the KStars Startup Wizard.
![][13]
Follow the prompts to choose your home location (where you will be imaging from) and *Download Extra Data…*
![][14]
![][15]
![][16]
This will allow you to install additional star, nebula, and galaxy catalogs. You dont need them, but they dont take up too much space and add to the experience of using KStars. Once youve completed this, hit *Done* in the bottom right corner to continue.
### Getting familiar with KStars
Now is a good time to play around with the KStars interface. You are greeted with a spherical image with a coordinate plane and stars in the sky.
![][17]
This is the desktop planetarium which allows you to view the placement of objects in the night sky. Double-clicking an object selects it, and right clicking on an object gives you options like *Center & Track* which will follow the object in the planetarium, compensating for [sidereal time][18]. *Show DSS Image* shows a real [digitized sky survey][19] image of the selected object.
![][20]
Another essential feature is the *Set Time* option in the toolbar. Clicking this will allow you to input a future (or past) time and then simulate the night sky as if that were the current date.
![][21]
### Configuring capture equipment with Ekos
Youre familiar with the KStars layout and some basic functions, so its time to move on configuring your equipment using the [Ekos][22] observatory controller and automation tool. To open Ekos, click the observatory button in the toolbar or go to *Tools* > *Ekos*.
![][23]
You will see another setup wizard: the *Ekos Profile Wizard*. Click *Next* to start the wizard.
![][24]
In this tutorial, you have all of our equipment connected directly to your computer. A future article we will cover using an INDI server installed on a remote computer to control our equipment, allowing you to connect over a network and not have to be in the same physical space as your gear. For now though, select *Equipment is attached to this device*.
![][25]
You are now asked to name your equipment profile. I usually name mine something like “Local Gear” to differentiate between profiles that are for remote gear, but name your profile what you wish. We will leave the button marked *Internal Guide* checked and wont select any additional services. Now click the *Create Profile & Select Devices* button.
![][26]
This next screen is where we can select your particular driver to use for each individual piece of equipment. This part will be specific to your setup depending on what gear you use. For this tutorial, I will select the drivers for my setup.
My mount, a [SkyWatcher EQM-35 Pro][27], uses the *EQMod Mount* under *SkyWatcher* in the menu (this driver is also compatible with all SkyWatcher equatorial mounts, including the [EQ6-R Pro][28] and the [EQ8-R Pro][29]). For my Sony a6000 imaging camera, I choose the *Sony DSLR* under *DSLRs* under the CCD category. Under *Guider*, I choose the *QHY CCD* under *QHY* for my Orion Starshoot (and any QHY5 series camera). That last driver we want to select will be under the Aux 1 category. We want to select *Astrometry* from the drop-down window. This will enable the Astrometry plate-solver from within Ekos that will allow our telescope to automatically figure out where in the night sky it is pointed, saving us the time and hassle of doing a one, two, or three star calibration after setting up our mount.
You selected your drivers. Now its time to configure your telescope. Add new telescope profiles by clicking on the + button in the lower right. This is essential for computing field-of-view measurements so you can tell what your images will look like when you open the shutter. Once you click the + button, you will be presented with a form where you can enter the specifications of your telescope and guide scope. For my imaging telescope, I will enter Celestron into the *Vendor* field, SS-80 into the *Model* field, I will leave the *Driver* field as None, *Type* field as Refractor, *Aperture* as 80mm, and *Focal Length* as 400mm.
![][30]
After you enter the data, hit the *Save* button. You will see the data you just entered appear in the left window with an index number of 1 next to it. Now you can go about entering the specs for your guide scope following the steps above. Once you hit save here, the guide scope will also appear in the left window with an index number of 2. Once all of your scopes are entered, close this window. Now select your *Primary* and *Guide* telescopes from the drop-down window.
![][31]
After all that work, everything should be correctly configured! Click the *Close* button and complete the final bit of setup.
### Starting your capture equipment
This last step before you can start taking images should be easy enough. Click the *Play* button under Start & Stop Ekos to connect to your equipment.
![][32]
You will be greeted with a screen that looks similar to this:
![][33]
When you click on the tabs at the top of the screen, they should all show a green dot next to *Connection*, indicating that they are connected to your system. On my setup, the baud rate for my mount (the EQMod Mount tab) is set incorrectly, and so the mount is not connected.
![][34]
This is an easy fix; click on the *EQMod Mount* tab, then the *Connection* sub-tab, and then change the baud rate from 9600 to 115200. Now is a good time to ensure the serial port under *Ports* is the correct serial port for your mount. You can check which port the system has mounted your device on by running the command:
```
ls /dev
| grep USB
```
You should see *ttyUSB0*. If there is more than one USB-serial device plugged in at a time, you will see more than one ttyUSB port, with an incrementing following number. To figure out which port is correct. unplug your mount and run the command again.
Now click on the *Main Control* sub-tab, click *Connect* again, and wait for the mount to connect. It might take a few seconds, be patient and it should connect.
The last thing to do is set the sensor and pixel size parameters for my camera. Under the *Sony DSLR Alpha-A6000 (Control)* tab, select the *Image Info* sub-tab. This is where you can enter your sensor specifications; if you dont know them, a quick search on the internet will bring you your sensors maximum resolution as well as pixel pitch. Enter this data into the right-side boxes, then press the *Set* button to load them into the left boxes and save them into memory. Hit the *Close* button when you are done.
![][35]
### Conclusion
Your equipment is ready to use. In the next article, you will learn how to capture and process the images.
--------------------------------------------------------------------------------
via: https://fedoramagazine.org/astrophotography-with-fedora-astronomy-lab-setting-up/
作者:[Geoffrey Marr][a]
选题:[lkxed][b]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://fedoramagazine.org/author/coremodule/
[b]: https://github.com/lkxed
[1]: https://fedoramagazine.org/wp-content/uploads/2021/02/astrophotography-setup-2-816x345.jpg
[2]: https://fedoramagazine.org/wp-content/uploads/2020/11/IMG_4151-768x1024.jpg
[3]: https://labs.fedoraproject.org/en/astronomy/
[4]: https://labs.fedoraproject.org/astronomy/download/index.html
[5]: https://github.com/FedoraQt/MediaWriter
[6]: https://docs.fedoraproject.org/en-US/fedora/f33/install-guide/install/Preparing_for_Installation/#_fedora_media_writer
[7]: https://docs.fedoraproject.org/en-US/fedora/f33/install-guide/install/Booting_the_Installation/
[8]: https://docs.fedoraproject.org/en-US/fedora/f33/install-guide/install/Installing_Using_Anaconda/#sect-installation-graphical-mode
[9]: https://www.qhyccd.com/html/prepub/log_en.html#!log_en.md
[10]: https://www.indilib.org/download/fedora/category/8-fedora.html
[11]: https://fedoramagazine.org/wp-content/uploads/2020/11/lsusb_output_rpi.png
[12]: https://edu.kde.org/kstars/
[13]: https://fedoramagazine.org/wp-content/uploads/2020/11/kstars_setuo_wizard-2.png
[14]: https://fedoramagazine.org/wp-content/uploads/2020/11/kstars_location_select-2.png
[15]: https://fedoramagazine.org/wp-content/uploads/2020/11/kstars-download-extra-data-1.png
[16]: https://fedoramagazine.org/wp-content/uploads/2020/11/kstars_install_extra_Data-1.png
[17]: https://fedoramagazine.org/wp-content/uploads/2020/11/kstars_planetarium-1024x549.png
[18]: https://en.wikipedia.org/wiki/Sidereal_time
[19]: https://en.wikipedia.org/wiki/Digitized_Sky_Survey
[20]: https://fedoramagazine.org/wp-content/uploads/2020/11/kstars_right_click_object-1024x576.png
[21]: https://fedoramagazine.org/wp-content/uploads/2020/11/kstars_planetarium_clock_icon.png
[22]: https://www.indilib.org/about/ekos.html
[23]: https://fedoramagazine.org/wp-content/uploads/2020/11/open_ekos_icon.png
[24]: https://fedoramagazine.org/wp-content/uploads/2020/11/ekos-profile-wizard.png
[25]: https://fedoramagazine.org/wp-content/uploads/2020/11/ekos_equipment_attached_to_this_device.png
[26]: https://fedoramagazine.org/wp-content/uploads/2020/11/ekos_wizard_local_gear.png
[27]: https://www.skywatcherusa.com/products/eqm-35-mount
[28]: https://www.skywatcherusa.com/products/eq6-r-pro
[29]: https://www.skywatcherusa.com/collections/eq8-r-series-mounts/products/eq8-r-mount-with-pier-tripod
[30]: https://fedoramagazine.org/wp-content/uploads/2020/11/setup_telescope_profiles.png
[31]: https://fedoramagazine.org/wp-content/uploads/2020/11/ekos_setup_aux_1_astrometry-1024x616.png
[32]: https://fedoramagazine.org/wp-content/uploads/2020/11/ekos_start_equip_connect.png
[33]: https://fedoramagazine.org/wp-content/uploads/2020/11/ekos_startup_equipment.png
[34]: https://fedoramagazine.org/wp-content/uploads/2020/11/set_baud_rate_to_115200.png
[35]: https://fedoramagazine.org/wp-content/uploads/2020/11/set_camera_sensor_settings.png

View File

@@ -1,190 +0,0 @@
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (Integrate devices and add-ons into your home automation setup)
[#]: via: (https://opensource.com/article/21/2/home-automation-addons)
[#]: author: (Steve Ovens https://opensource.com/users/stratusss)
Integrate devices and add-ons into your home automation setup
======
Learn how to set up initial integrations and install add-ons in Home
Assistant in the fifth article in this series.
![Looking at a map][1]
In the four previous articles in this series about home automation, I have discussed [what Home Assistant is][2], why you may want [local control][3], some of the [communication protocols][4] for smart home components, and how to [install Home Assistant][5] in a virtual machine (VM) using libvirt. In this fifth article, I will talk about configuring some initial integrations and installing some add-ons.
### Set up initial integrations
It's time to start getting into some of the fun stuff. The whole reason Home Assistant (HA) exists is to pull together various "smart" devices from different manufacturers. To do so, you have to make Home Assistant aware of which devices it should coordinate. I'll demonstrate by adding a [Sonoff Zigbee Bridge][6].
I followed [DigiBlur's Sonoff Guide][7] to replace the stock firmware with the open source firmware [Tasmota][8] to decouple my sensors from the cloud. My [second article][3] in this series explains why you might wish to replace the stock firmware. (I won't go into the device's setup with either the stock or custom firmware, as that is outside of the scope of this tutorial.)
First, navigate to the **Configuration** menu on the left side of the HA interface, and make sure **Integrations** is selected:
![Home Assistant integration configuration][9]
(Steve Ovens, [CC BY-SA 4.0][10])
From there, click the **Add Integration** button in the bottom-right corner and search for Zigbee:
![Add Zigbee integration in Home Assistant][11]
(Steve Ovens, [CC BY-SA 4.0][10])
Enter the device manually. If the Zigbee Bridge was physically connected to the Home Assistant interface, you could select the device path. For instance, I have a ZigBee CC2531 USB stick that I use for some Zigbee devices that do not communicate correctly with the Sonoff Bridge. It attaches directly to the Home Assistant host and shows up as a Serial Device. See my [third article][12] for details on wireless standards. However, in this tutorial, we will continue to configure and use the Sonoff Bridge.
![Enter device manually][13]
(Steve Ovens, [CC BY-SA 4.0][10])
The next step is to choose the radio type, using the information in the DigiBlur tutorial. In this case, the radio is an EZSP radio:
![Choose the radio type][14]
(Steve Ovens, [CC BY-SA 4.0][10])
Finally, you need to know the IP address of the Sonoff Bridge, the port it is listening on, and the speed of the connection. Once I found the Sonoff Bridge's MAC address, I used my DHCP server to ensure that the device always uses the same IP on my network. DigiBlur's guide provides the port and speed numbers.
![IP, port, and speed numbers][15]
(Steve Ovens, [CC BY-SA 4.0][10])
Once you've added the Bridge, you can begin pairing devices to it. Ensure that your devices are in pairing mode. The Bridge will eventually find your device(s).
![Device pairing][16]
(Steve Ovens, [CC BY-SA 4.0][10])
You can name the device(s) and assign an area (if you set them up).
![Name device][17]
(Steve Ovens, [CC BY-SA 4.0][10])
The areas displayed will vary based on whether or not you have any configured. Bedroom, Kitchen, and Living Room exist by default. As you add a device, HA will add a new Card to the **Integrations** tab. A Card is a user interface (UI) element that groups information related to a specific entity. The Zigbee card looks like this:
![Integration card][18]
(Steve Ovens, [CC BY-SA 4.0][10])
Later, I'll come back to using this integration. I'll also get into how to use this device in automation flows. But now, I will show you how to add functionality to Home Assistant to make your life easier.
### Add functionality with add-ons
Out of the box, HA has some pretty great features for home automation. If you are buying commercial-off-the-shelf (CoTS) products, there is a good chance you can accomplish everything you need without the help of add-ons. However, you may want to investigate some of the add-ons, especially if (like me) you want to make your own sensors.
There are all kinds of HA add-ons, ranging from Android debugging (ADB) tools to MQTT brokers to the Visual Studio Code editor. With each release, the number of add-ons grows. Some people make HA the center of their local system, encompassing DHCP, Plex, databases, and other useful programs. In fact, HA now ships with a built-in media browser for playing any media that you expose to it.
I won't go too crazy in this article; I'll show you some of the basics and let you decide how you want to proceed.
#### Install official add-ons
Some of the many HA add-ons are available for installation right from the web UI, and others can be installed from alternative sources, such as Git.
To see what's available, click on the **Supervisor** menu on the left panel. Near the top, you will see a tab called **Add-on store**.
![Home Assistant add-on store][19]
(Steve Ovens, [CC BY-SA 4.0][10])
Below are three of the more useful add-ons that I think should be standard for any HA deployment:
![Home Assistant official add-ons][20]
(Steve Ovens, [CC BY-SA 4.0][10])
The **File Editor** allows you to manage Home Assistant configuration files directly from your browser. I find this far more convenient for quick edits than obtaining a copy of the file, editing it, and pushing it back to HA. If you use add-ons like the Visual Studio Code editor, you can edit the same files.
The **Samba share** add-on is an excellent way to extract HA backups from the system or push configuration files or assets to the **web** directory. You should _never_ leave your backups sitting on the machine being backed up.
Finally, **Mosquitto broker** is my preferred method for managing an [MQTT][21] client. While you can install a broker that's external to the HA machine, I find low value in doing this. Since I am using MQTT just to communicate with my IoT devices, and HA is the primary method of coordinating that communication, there is a low risk in having these components vertically integrated. If HA is offline, the MQTT broker is almost useless in my arrangement.
#### Install community add-ons
Home Assistant has a prolific community and passionate developers. In fact, many of the "community" add-ons are developed and maintained by the HA developers themselves. For my needs, I install:
![Home Assistant community add-ons][22]
(Steve Ovens, [CC BY-SA 4.0][10])
**Grafana** (graphing program) and **InfluxDB** (a time-series database) are largely optional and relate to the ability to customize how you visualize the data HA collects. I like to have historical data handy and enjoy looking at the graphs from time to time. While not exactly HA-related, I have my pfSense firewall/router forward metrics to InfluxDB so that I can make some nice graphs over time.
![Home Assistant Grafana add-on][23]
(Steve Ovens, [CC BY-SA 4.0][10])
**ESPHome** is definitely an optional add-on that's warranted only if you plan on making your own sensors.
**NodeRED** is my preferred automation flow-handling solution. Although HA has some built-in automation, I find a visual flow editor is preferable for some of the logic I use in my system.
#### Configure add-ons
Some add-ons (such as File Editor) require no configuration to start them. However, most—such as Node-RED—require at least a small amount of configuration. Before you can start Node-RED, you will need to set a password:
![Home Assistant Node-RED add-on][24]
(Steve Ovens, [CC BY-SA 4.0][10])
**IMPORTANT:** Many people will abstract passwords through the `secrets.yaml` file. This does not provide any additional security other than not having passwords in the add-on configuration's YAML. See [the official documentation][25] for more information.
In addition to the password requirement, most of the add-ons that have a web UI default to having the `ssl: true` option set. A self-signed cert on my local LAN is not a requirement, so I usually set this to false. There is an add-on for Let's Encrypt, but dealing with certificates is outside the scope of this series.
After you have looked through the **Configuration** tab, save your changes, and enable Node-RED on the add-on's main screen.
![Home Assistant Node-RED add-on][26]
(Steve Ovens, [CC BY-SA 4.0][10])
Don't forget to start the plugin.
Most add-ons follow a similar procedure, so you can use this approach to set up other add-ons.
### Wrapping up
Whew, that was a lot of screenshots! Fortunately, when you are doing the configuration, the UI makes these steps relatively painless.
At this point, your HA instance should be installed with some basic configurations and a few essential add-ons.
In the next article, I will discuss integrating custom Internet of Things (IoT) devices into Home Assistant. Don't worry; the fun is just beginning!
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/2/home-automation-addons
作者:[Steve Ovens][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/stratusss
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/tips_map_guide_ebook_help_troubleshooting_lightbulb_520.png?itok=L0BQHgjr (Looking at a map)
[2]: https://opensource.com/article/20/11/home-assistant
[3]: https://opensource.com/article/20/11/cloud-vs-local-home-automation
[4]: https://opensource.com/article/20/11/home-automation-part-3
[5]: https://opensource.com/article/20/12/home-assistant
[6]: https://sonoff.tech/product/smart-home-security/zbbridge
[7]: https://www.digiblur.com/2020/07/how-to-use-sonoff-zigbee-bridge-with.html
[8]: https://tasmota.github.io/docs/
[9]: https://opensource.com/sites/default/files/uploads/ha-setup20-configuration-integration.png (Home Assistant integration configuration)
[10]: https://creativecommons.org/licenses/by-sa/4.0/
[11]: https://opensource.com/sites/default/files/uploads/ha-setup21-int-zigbee.png (Add Zigbee integration in Home Assistant)
[12]: https://opensource.com/article/20/11/wireless-protocol-home-automation
[13]: https://opensource.com/sites/default/files/uploads/ha-setup21-int-zigbee-2.png (Enter device manually)
[14]: https://opensource.com/sites/default/files/uploads/ha-setup21-int-zigbee-3.png (Choose the radio type)
[15]: https://opensource.com/sites/default/files/uploads/ha-setup21-int-zigbee-4.png (IP, port, and speed numbers)
[16]: https://opensource.com/sites/default/files/uploads/ha-setup21-int-zigbee-5.png (Device pairing)
[17]: https://opensource.com/sites/default/files/uploads/ha-setup21-int-zigbee-6.png (Name device)
[18]: https://opensource.com/sites/default/files/uploads/ha-setup21-int-zigbee-7_0.png (Integration card)
[19]: https://opensource.com/sites/default/files/uploads/ha-setup7-addons.png (Home Assistant add-on store)
[20]: https://opensource.com/sites/default/files/uploads/ha-setup8-official-addons.png (Home Assistant official add-ons)
[21]: https://en.wikipedia.org/wiki/MQTT
[22]: https://opensource.com/sites/default/files/uploads/ha-setup9-community-addons.png (Home Assistant community add-ons)
[23]: https://opensource.com/sites/default/files/uploads/ha-setup9-community-grafana-pfsense.png (Home Assistant Grafana add-on)
[24]: https://opensource.com/sites/default/files/uploads/ha-setup27-nodered2.png (Home Assistant Node-RED add-on)
[25]: https://www.home-assistant.io/docs/configuration/secrets/
[26]: https://opensource.com/sites/default/files/uploads/ha-setup26-nodered1.png (Home Assistant Node-RED add-on)

View File

@@ -1,219 +0,0 @@
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (Fedora Aarch64 on the SolidRun HoneyComb LX2K)
[#]: via: (https://fedoramagazine.org/fedora-aarch64-on-the-solidrun-honeycomb-lx2k/)
[#]: author: (John Boero https://fedoramagazine.org/author/boeroboy/)
Fedora Aarch64 on the SolidRun HoneyComb LX2K
======
![][1]
Photo by [Tim Mossholder][2] on [Unsplash][3]
Almost a year has passed since the [HoneyComb][4] development kit was released by SolidRun. I remember reading about this Mini-ITX Arm workstation board being released and thinking “what a great idea.” Then I saw the price and realized this isnt just another Raspberry Pi killer. Currently that price is $750 USD plus shipping and duty. Niche devices like the HoneyComb arent mass produced like the simpler Pi is, and they pack in quite a bit of high end tech. Eventually COVID lockdown boredom got the best of me and I put a build together. Adding a case and RAM, the build ended up costing about $1100 shipped to London. This is a recount of my experiences and the current state of using Fedora on this fun bit of hardware.
First and foremost, the tech packed into this board is impressive. Its not about to kill a Xeon workstation in raw performance but its going to wallop it in performance/watt efficiency. Essentially this is a powerful server in the energy footprint of a small laptop. Its also a powerful hybrid of compute and network functionality, combining powerful network features in a carrier board with modular daughter card sporting a 16-core A72 with 2 ECC-capable DDR4 SO-DIMM slots. The carrier board comes in a few editions, giving flexibility to swap or upgrade your RAM + CPU options. I purchased the edition pictured below with 16 cores, 32GB (non-ECC), 512GB NVMe, and 4x10Gbe. For an extra $250 you can add the 100Gbe option if youre building a 5G deployment or an ISP for a small country (bottom right of board). Imagine this jacked into a 100Gb uplink port acting as proxy, tls inspector, router, or storage for a large 10gb TOR switch.
![][5]
When I ordered it I didnt fully understand the network co processor included from NXP. NXP is the company that makes the unique [LX2160A][6] CPU/SOC for this as well as configurable ports and offload engine that enable handling up to 150Gb/s of network traffic without the CPU breaking a sweat. Here is a list of options from NXPs Layerscape user manual.
![Configure ports in switch, LAG, MUX mode, or straight NICs.][7]
I have a 10gb network in my home attic via a Ubiquiti ES-16-XG so I was eager to see how much this board could push. I also have a QNAP connected via 10gb which rarely manages to saturate the line, so could this also be a NAS replacement? It turned out I needed to sort out drivers and get a stable install first. Since the board has been out for a year, I had some catching up to do. SolidRun keeps an active Discord on [Developer-Ecosystem][8] which was immensely helpful as install wasnt as straightforward as previous blogs have mentioned. Ive always been cursed. If youve ever seen Pure Luck, Im bound to hit every hardware glitch.
![][9]
For starters, you can add a GPU and install graphically or install via USB console. I started with a spare GPU (Radeon Pro WX2100) intending to build a headless box which in the end over-complicated things. If you need to swap parts or re-flash a BIOS via the microSD card, youll need to swap display, keyboard + mouse. Chaos. Much simpler just to plug into the micro USB console port and access it via /dev/ttyUSB0 for that picture-in-picture experience. Its really great to have the open ended PCIe3-x8 slot but Ill keep it open for now. Note that the board does not support PCIe Atomics so some devices may have compatibility issues.
Now comes the fun part. BIOS is not built-in here. Youll need to [build][10] from source for to your RAM speed and install via microSDHC. At first this seems annoying but then you realize that with removable BIOS installer its pretty hard to brick this thing. Not bad. The good news is the latest UEFI builds have worked well for me. Just remember that every time you re-flash your BIOS youll need to set everything up again. This was enough to boot Fedora aarch64 from USB. The board offers 64GB of eMMC flash which you can install to if you like. I immediately benched it to find it reads about 165MB/s and writes 55MB/s which is practical speed for embedded usage but Ill definitely be installing to NVMe instead. I had an older Samsung 950 Pro in my spares from a previous Linux box but I encountered major issues with it even with the widely documented kernel param workaround:
```
```
nvme_core.default_ps_max_latency_us=0
```
```
In the end I upgraded my main workstation so I could repurpose its existing Samsung EVO 960 for the HoneyComb which worked much better.
After some fidgeting I was able to install Fedora but it became apparent that the integrated network ports still dont work with the mainline kernel. The NXP tech is great but requires a custom kernel build and tooling. Some earlier blogs got around this with a USB->RJ45 Ethernet adapter which works fine. Hopefully network support will be mainlined soon, but for now I snagged a kernel SRPM from the helpful engineers on Discord. With the custom kernel the 1Gbe NIC worked fine, but it turns out the SFP+ ports need more configuration. They wont be recognized as interfaces until you use NXPs _restool_ utility to map ports to their usage. In this case just a runtime mapping of _dmap -> dni_ was required. This is NXPs way of mapping a MAC to a network interface via IOCTL commands. The restool binary isnt provided either and must be built from source. It then layers on management scripts which use cheeky $arg0 references for redirection to call the restool binary with complex arguments.
Since I was starting to accumulate quite a few custom packages it was apparent that a COPR repo was needed to simplify this for Fedora. If youre not familiar with COPR I think its one of Fedoras finest resources. This repo contains the uefi build (currently failing build), 5.10.5 kernel built with network support, and the restool binary with supporting scripts. I also added a oneshot systemd unit to enable the SFP+ ports on boot:
```
```
systemd enable --now [dpmac@7.service][11]
systemd enable --now [dpmac@8.service][12]
systemd enable --now [dpmac@9.service][13]
systemd enable --now [dpmac@10.service][14]
```
```
Now each SPF+ port will boot configured as eth1-4, with eth0 being the 1Gb. NetworkManager will struggle unless these are consistent, and if you change the service start order the eth devices will re-order. I actually put a sleep $@ in each activation so they are consistent and dont have locking issues. Unfortunately it adds 10 seconds to boot time. This has been fixed in the latest kernel and wont be an issue once mainlined.
![][15]
Id love to explore the built-in LAG features but this still needs to be coded into the
restool
options. Ill save it for later. In the meantime I managed a single 10gb link as primary, and a 3×10 LACP Team for kicks. Eventually I changed to 4×10 LACP via copper SFP+ cables mounted in the attic.
### Energy Efficiency
Now with a stable environment its time to raise some hell. Its really nice to see PWM support was recently added for the CPU fan, which sounds like a mini jet engine without it. Now the sound level is perfectly manageable and thermal control is automatic. Time to test drive with a power meter. Total power usage is consistently between 20-40 watts (usually in the low 20s) which is really impressive. I tried a few _tuned_ profiles which didnt seem to have much effect on energy. If you add a power-hungry GPU or device that can obviously increase but for a dev server its perfect and well below the Z600 workstations I have next to it which consume 160-250 watts each when fired up.
### Remote Access
Im an old soul so I still prefer KDE with Xorg and NX via X2go server. I can access SSH or a full GUI at native performance without a GPU. This lets me get a feel for performance, thermal stats, and also helps to evaluate the device as a workstation or potential VDI. The version of KDE shipped with the aarch64 server spin doesnt seem to recognize some sensors but that seems to be because of KDEs latest widget changes which Id have to dig into.
![X2go KDE session over SSH][16]
Cockpit support is also outstanding out of the box. If SSH and X2go remote access arent your thing, Cockpit provides a great remote management platform with a growing list of plugins. Everything works great in my experience.
![Cockpit behaves as expected.][17]
All I needed to do now is shift into high gear with jumbo frames. MTU 1500 yields me an iperf of about 2-4Gbps bottlenecked at CPU0. Aint nobody got time for that. Set MTU 9000 and suddenly it gets the full 10Gbps both ways with time to spare on the CPU. Again, it would be nice to use the hardware assisted LAG since the device is supposed to handle up to 150Gbps duplex no sweat (with the 100Gbe QSFP option), which is nice given the Ubiquiti ES-16-XG tops out at 160Gbps full duplex (10gb/16 ports).
### Storage
As a storage solution this hardware provides great value in a small thermal window and energy saving footprint. I could accomplish similar performance with an old x86 box for cheap but the energy usage alone would eclipse any savings in short order. By comparison Ive seen some consumer NAS devices offer 10Gbe and NVMe cache sharing an inadequate number of PCIe2 lanes and bottlenecked at the bus. This is fully customizable and since the energy footprint is similar to a small laptop a small UPS backup should allow full writeback cache mode for maximum performance. This would make a great oVirt NFS or iSCSI storage pool if needed. I would pair it with a nice NAS case or rack mount case with bays. Some vendors such as [Bamboo][18] are actually building server options around this platform as we speak.
The board has 4 SATA3 ports but if I were truly going to build a NAS with this I would probably add a RAID card that makes best use of the PCIe8x slot, which thankfully is open ended. Why some hardware vendors choose to include close-ended PCIe 8x,4x slots is beyond me. Future models will ship with a physical x16 slot but only 8x electrically. Some users on the SolidRun Discord talk about bifurcation and splitting out the 8 PCIe lanes which is an option as well. Note that some of those lanes are also reserved for NVMe, SATA, and network. The CEX7 form factor and interchangeable carrier board presents interesting possibilities later as the NXP LX2160A docs claim to support up to 24 lanes. For a dev board its perfectly fine as-is.
### Network Perf
For now Ive managed to rig up a 4×10 LACP Team with NetworkManager for full load balancing. This same setup can be done with a QSFP+ breakout cable. KDE nm Network widget still doesnt support Teams but I can set them up via nm-connection-editor or Cockpit. Automation could be achieved with _nmcli_ and _teamdctl_. An iperf3 test shows the connection maxing out at about 13Gbps to/from the 2×10 LACP team on my workstation. I know that iperf isnt a true indication of real-world usage but its fun for benchmarks and tuning nonetheless. This did in fact require a lot of tuning and at this point I feel like I could fill a book just with iperf stats.
```
$ iperf3 -c honeycomb -P 4 --cport 5000 -R
Connecting to host honeycomb, port 5201
Reverse mode, remote host honeycomb is sending
[ 5] local 192.168.2.10 port 5000 connected to 192.168.2.4 port 5201
[ 7] local 192.168.2.10 port 5001 connected to 192.168.2.4 port 5201
[ 9] local 192.168.2.10 port 5002 connected to 192.168.2.4 port 5201
[ 11] local 192.168.2.10 port 5003 connected to 192.168.2.4 port 5201
[ ID] Interval Transfer Bitrate
[ 5] 1.00-2.00 sec 383 MBytes 3.21 Gbits/sec
[ 7] 1.00-2.00 sec 382 MBytes 3.21 Gbits/sec
[ 9] 1.00-2.00 sec 383 MBytes 3.21 Gbits/sec
[ 11] 1.00-2.00 sec 383 MBytes 3.21 Gbits/sec
[SUM] 1.00-2.00 sec 1.49 GBytes 12.8 Gbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
(TRUNCATED)
- - - - - - - - - - - - - - - - - - - - - - - - -
[ 5] 2.00-3.00 sec 380 MBytes 3.18 Gbits/sec
[ 7] 2.00-3.00 sec 380 MBytes 3.19 Gbits/sec
[ 9] 2.00-3.00 sec 380 MBytes 3.18 Gbits/sec
[ 11] 2.00-3.00 sec 380 MBytes 3.19 Gbits/sec
[SUM] 2.00-3.00 sec 1.48 GBytes 12.7 Gbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bitrate Retr
[ 5] 0.00-10.00 sec 3.67 GBytes 3.16 Gbits/sec 1 sender
[ 5] 0.00-10.00 sec 3.67 GBytes 3.15 Gbits/sec receiver
[ 7] 0.00-10.00 sec 3.68 GBytes 3.16 Gbits/sec 7 sender
[ 7] 0.00-10.00 sec 3.67 GBytes 3.15 Gbits/sec receiver
[ 9] 0.00-10.00 sec 3.68 GBytes 3.16 Gbits/sec 36 sender
[ 9] 0.00-10.00 sec 3.68 GBytes 3.16 Gbits/sec receiver
[ 11] 0.00-10.00 sec 3.69 GBytes 3.17 Gbits/sec 1 sender
[ 11] 0.00-10.00 sec 3.68 GBytes 3.16 Gbits/sec receiver
[SUM] 0.00-10.00 sec 14.7 GBytes 12.6 Gbits/sec 45 sender
[SUM] 0.00-10.00 sec 14.7 GBytes 12.6 Gbits/sec receiver
iperf Done
```
### Notes on iperf3
I struggled with LACP Team configuration for hours, having done this before with an HP cluster on the same switch. Id heard stories about bonds being old news with team support adding better load balancing to single TCP flows. This still seems bogus as you still cant load balance a single flow with a team in my experience. Also LACP claims to be fully automated and easier to set up than traditional load balanced trunks but I find the opposite to be true. For all it claims to automate you still need to have hashing algorithms configured correctly at switches and host. With a few quirks along the way I once accidentally left a team in broadcast mode (not LACP) which registered duplicate packets on the iperf server and made it look like a single connection was getting double bandwidth. That mistake caused confusion as I tried to reproduce it with LACP.
Then I finally found the LACP hash settings in Ubiquitis new firmware GUI. Its hidden behind a tiny pencil icon on each LAG. I managed to set my LAGs to hash on Src+Dest IP+port when they were defaulting to MAC/port. Still I was only seeing traffic on one slave of my 2×10 team even with parallel clients. Eventually I tried parallel clients with -V and it all made sense. By default iperf3 client ports are ephemeral but they follow an even sequence: 42174, 42176, 42178, 42180, etc… If your lb hash across a pair of sequential MACs includes src+dst port but those ports are always even, youll never hit the other interface with an odd MAC. How crazy is that for iperf to do? I tried looking at the source for iperf3 and I dont even see how that could be happening. Instead if you specify a client port as well as parallel clients, they use a straight sequence: 50000, 50001, 50002, 50003, etc.. With odd+even numbers in client ports, Im finally able to LB across all interfaces in all LAG groups. This setup would scale out well with more clients on the network.
![Proper LACP load balancing.][19]
Everything could probably be tuned a bit better but for now it is excellent performance and it puts my QNAP to shame. Ill continue experimenting with the network co-processor and seeing if I can enable the native LAG support for even better performance. Across the network I would expect a practical peak of about 40 Gbps raw which is great.
![][20]
### Virtualization
What about virt? One of the best parts about having a 16 A72 cores is support for Aarch64 VMs at full speed using KVM, which you wont be able to do on x86. I can use this single box to spin up a dozen or so VMs at a time for CI automation and testing, or just to test our latest HashiCorp builds with aarch64 builds on COPR. Qemu on x86 without KVM can emulate aarch64 but crawls by comparison. Ive not yet tried to add it to an oVirt cluster yet but its really snappy actually and proves more cost effective than spinning up Arm VMs in a cloud. One of the use cases for this environment is NFV, and I think it fits it perfectly so long as you pair it with ECC RAM which I skipped as Im not running anything critical. If anybody wants to test drive a VM DM me and Ill try to get you some temp access.
![Virtual Machines in Cockpit][21]
### Benchmarks
[Phoronix][22] has already done quite a few benchmarks on [OpenBenchmarking.org][23] but I wanted to rerun them with the latest versions on my own Fedora 33 build for consistency. I also wanted to compare them to my Xeons which is not really a fair comparison. Both use DDR4 with similar clock speeds around 2Ghz but different architectures and caches obviously yield different results. Also the Xeons are dual socket which is a huge cooling advantage for single threaded workloads. You can watch one process bounce between the coolest CPU sockets. The Honeycomb doesnt have this luxury and has a smaller fan but the clock speed is playing it safe and slow at 2Ghz so I would bet the SoC has room to run faster if cooling were adjusted. I also havent played with the PWM settings to adjust the fan speed up just in case. Benchmarks performed using the tuned profile network-throughput.
Strangely some single core operations seem to actually perform better on the Honeycomb than they do on my Xeons. I tried single-threaded zstd compression with default level 3 on a a few files and found it actually performs consistently better on the Honeycomb. However using the actual pts/compress-zstd benchmark with multithreaded option turns the tables. The 16 cores still manage an impressive **2073** MB/s:
```
```
Zstd Compression 1.4.5:
   pts/compress-zstd-1.2.1 &amp;#91;Compression Level: 3]
   Test 1 of 1
   Estimated Trial Run Count:    3                      
   Estimated Time To Completion: 9 Minutes &amp;#91;22:41 UTC]  
       Started Run 1 @ 22:33:02
       Started Run 2 @ 22:33:53
       Started Run 3 @ 22:34:37
   Compression Level: 3:
2079.3
2067.5
       2073.9
   Average: 2073.57 MB/s
```
```
For apples to oranges comparison my 2×10 core Xeon E5-2660 v3 box does **2790** MB/s, so 2073 seems perfectly respectable as a potential workstation. Paired with a midrange GPU this device would also make a great video transcoder or media server. Some users have asked about mining but I wouldnt use one of these for mining crypto currency. The lack of PCIe atomics means certain OpenCL and CUDA features might not be supported and with only 8 PCIe lanes exposed youre fairly limited. That said it could potentially make a great mobile ML, VR, IoT, or vision development platform. The possibilities are pretty open as the whole package is very well balanced and flexible.
### Conclusion
I wasnt organized enough this year to arrange a FOSDEM visit but this is something I would have loved to talk about. Im definitely glad I tried out. Special thanks to Jon Nettleton and the folks on SolidRuns Discord for the help and troubleshooting. The kit is powerful and potentially replaces a lot of energy waste in my home lab. It provides a great Arm platform for development and its great to see how solid Fedoras alternative architecture support is. I got my Linux start on Gentoo back in the day, but Fedora really has upped its arch game. Im really glad I didnt have to sit waiting for compilation on a proprietary platform. I look forward to the remaining patches to be mainlined into the Fedora kernel and I hope to see a few more generations use this package, especially as Apple goes all in on Arm. It will also be interesting to see what features emerge if Nvidias Arm acquisition goes through.
--------------------------------------------------------------------------------
via: https://fedoramagazine.org/fedora-aarch64-on-the-solidrun-honeycomb-lx2k/
作者:[John Boero][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://fedoramagazine.org/author/boeroboy/
[b]: https://github.com/lujun9972
[1]: https://fedoramagazine.org/wp-content/uploads/2021/02/honeycomb-fed-aarch64-816x346.jpg
[2]: https://unsplash.com/@timmossholder?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText
[3]: https://unsplash.com/s/photos/honeycombs?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText
[4]: http://solid-run.com/arm-servers-networking-platforms/honeycomb-workstation/#overview
[5]: https://www.solid-run.com/wp-content/uploads/2020/11/HoneyComb-layout-front.png
[6]: https://www.nxp.com/products/processors-and-microcontrollers/arm-processors/layerscape-processors/layerscape-lx2160a-processor:LX2160A
[7]: https://communityblog.fedoraproject.org/wp-content/uploads/2021/02/image-894x1024.png
[8]: https://discord.com/channels/620838168794497044
[9]: https://i.imgflip.com/11c7o.gif
[10]: https://github.com/SolidRun/lx2160a_uefi
[11]: mailto:dpmac@7.service
[12]: mailto:dpmac@8.service
[13]: mailto:dpmac@9.service
[14]: mailto:dpmac@10.service
[15]: https://communityblog.fedoraproject.org/wp-content/uploads/2021/02/image-2-1024x403.png
[16]: https://communityblog.fedoraproject.org/wp-content/uploads/2021/02/Screenshot_20210202_112051-1024x713.jpg
[17]: https://fedoramagazine.org/wp-content/uploads/2021/02/image-2-1024x722.png
[18]: https://www.bamboosystems.io/b1000n/
[19]: https://fedoramagazine.org/wp-content/uploads/2021/02/image-4-1024x245.png
[20]: http://systems.cs.columbia.edu/files/kvm-arm-logo.png
[21]: https://fedoramagazine.org/wp-content/uploads/2021/02/image-1024x717.png
[22]: https://www.phoronix.com/scan.php?page=news_item&px=SolidRun-ClearFog-ARM-ITX
[23]: https://openbenchmarking.org/result/1905313-JONA-190527343&obr_sor=y&obr_rro=y&obr_hgv=ClearFog-ITX

View File

@@ -1,290 +0,0 @@
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (How to set up custom sensors in Home Assistant)
[#]: via: (https://opensource.com/article/21/2/home-assistant-custom-sensors)
[#]: author: (Steve Ovens https://opensource.com/users/stratusss)
How to set up custom sensors in Home Assistant
======
Dive into the YAML files to set up custom sensors in the sixth article
in this home automation series.
![Computer screen with files or windows open][1]
In the last article in this series about home automation, I started digging into Home Assistant. I [set up a Zigbee integration][2] with a Sonoff Zigbee Bridge and installed a few add-ons, including Node-RED, File Editor, Mosquitto broker, and Samba. I wrapped up by walking through Node-RED's configuration, which I will use heavily later on in this series. The four articles before that one discussed [what Home Assistant is][3], why you may want [local control][4], some of the [communication protocols][5] for smart home components, and how to [install Home Assistant][6] in a virtual machine (VM) using libvirt.
In this sixth article, I'll walk through the YAML configuration files. This is largely unnecessary if you are just using the integrations supported in the user interface (UI). However, there are times, particularly if you are pulling in custom sensor data, where you have to get your hands dirty with the configuration files.
Let's dive in.
### Examine the configuration files
There are several potential configuration files you will want to investigate. Although everything I am about to show you _can_ be done in the main configuration.yaml file, it can help to split your configuration into dedicated files, especially with large installations.
Below I will walk through how I configure my system. For my custom sensors, I use the ESP8266 chipset, which is very maker-friendly. I primarily use [Tasmota][7] for my custom firmware, but I also have some components running [ESPHome][8]. Configuring firmware is outside the scope of this article. For now, I will assume you set up your devices with some custom firmware (or you wrote your own with [Arduino IDE][9] ).
#### The /config/configuration.yaml file
Configuration.yaml is the main file Home Assistant reads. For the following, use the File Editor you installed in the previous article. If you do not see File Editor in the left sidebar, enable it by going back into the **Supervisor** settings and clicking on **File Editor**. You should see a screen like this:
![Install File Editor][10]
(Steve Ovens, [CC BY-SA 4.0][11])
Make sure **Show in sidebar** is toggled on. I also always toggle on the **Watchdog** setting for any add-ons I use frequently.
Once that is completed, launch File Editor. There is a folder icon in the top-left header bar. This is the navigation icon. The `/config` folder is where the configuration files you are concerned with are stored. If you click on the folder icon, you will see a few important files:
![Configuration split files][12]
The following is a default configuration.yaml:
![Default Home Assistant configuration.yaml][13]
(Steve Ovens, [CC BY-SA 4.0][11])
The notation `script: !include scripts.yaml` indicates that Home Assistant should reference the contents of scripts.yaml anytime it needs the definition of a script object. You'll notice that each of these files correlates to files observed when the folder icon is clicked.
I added three lines to my configuration.yaml:
```
input_boolean: !include input_boolean.yaml
binary_sensor: !include binary_sensor.yaml
sensor: !include sensor.yaml
```
As a quick aside, I configured my MQTT settings (see Home Assistant's [MQTT documentation][14] for more details) in the configuration.yaml file:
```
mqtt:
  discovery: true
  discovery_prefix: homeassistant
  broker: 192.168.11.11
  username: mqtt
  password: superpassword
```
If you make an edit, don't forget to click on the Disk icon to save your work.
![Save icon in Home Assistant config][15]
(Steve Ovens, [CC BY-SA 4.0][11])
#### The /config/binary_sensor.yaml file
After you name your file in configuration.yaml, you'll have to create it. In the File Editor, click on the folder icon again. There is a small icon of a piece of paper with a **+** sign in its center. Click on it to bring up this dialog:
![Create config file][16]
(Steve Ovens, [CC BY-SA 4.0][11])
I have three main types of [binary sensors][17]: door, motion, and power. A binary sensor has only two states: on or off. All my binary sensors send their data to MQTT. See my article on [cloud vs. local control][4] for more information about MQTT.
My binary_sensor.yaml file looks like this:
```
 - platform: mqtt
    state_topic: "BRMotion/state/PIR1"
    name: "BRMotion"
    qos: 1
    payload_on: "ON"
    payload_off: "OFF"
    device_class: motion
   
  - platform: mqtt
    state_topic: "IRBlaster/state/PROJECTOR"
    name: "ProjectorStatus"
    qos: 1
    payload_on: "ON"
    payload_off: "OFF"
    device_class: power
   
  - platform: mqtt
    state_topic: "MainHallway/state/DOOR"
    name: "FrontDoor"
    qos: 1
    payload_on: "open"
    payload_off: "closed"
    device_class: door
```
Take a look at the definitions. Since `platform` is self-explanatory, start with `state_topic`.
* `state_topic`, as the name implies, is the topic where the device's state is published. This means anyone subscribed to the topic will be notified any time the state changes. This path is completely arbitrary, so you can name it anything you like. I tend to use the convention `location/state/object`, as this makes sense for me. I want to be able to reference all devices in a location, and for me, this layout is the easiest to remember. Grouping by device type is also a valid organizational layout.
* `name` is the string used to reference the device inside Home Assistant. It is normally referenced by `type.name`, as seen in this card in the Home Assistant [Lovelace][18] interface:
![Binary sensor card][19]
(Steve Ovens, [CC BY-SA 4.0][11])
* `qos`, short for quality of service, refers to how an MQTT client communicates with the broker when posting to a topic.
* `payload_on` and `payload_off` are determined by the firmware. These sections tell Home Assistant what text the device will send to indicate its current state.
* `device_class:` There are multiple possibilities for a device class. Refer to the [Home Assistant documentation][17] for more information and a description of each type available.
#### The /config/sensor.yaml file
This file differs from binary_sensor.yaml in one very important way: The sensors within this configuration file can have vastly different data inside their payloads. Take a look at one of the more tricky bits of sensor data, temperature.
Here is the definition for my DHT temperature sensor:
```
 - platform: mqtt
    state_topic: "Steve_Desk_Sensor/tele/SENSOR"
    name: "Steve Desk Temperature"
    value_template: '{{ value_json.DHT11.Temperature }}'
   
  - platform: mqtt
    state_topic: "Steve_Desk_Sensor/tele/SENSOR"
    name: "Steve Desk Humidity"
    value_template: '{{ value_json.DHT11.Humidity }}'
```
You'll notice two things right from the start. First, there are two definitions for the same `state_topic`. This is because this sensor publishes three different statistics.
Second, there is a new definition of `value_template`. Most sensors, whether custom or not, send their data inside a JSON payload. The template tells Home Assistant where the important information is in the JSON file. The following shows the raw JSON coming from my homemade sensor. (I used the program `jq` to make the JSON more readable.)
```
{
  "Time": "2020-12-23T16:59:11",
  "DHT11": {
    "Temperature": 24.8,
    "Humidity": 32.4,
    "DewPoint": 7.1
  },
  "BH1750": {
    "Illuminance": 24
  },
  "TempUnit": "C"
}
```
There are a few things to note here. First, as the sensor data is stored in a time-based data store, every reading has a `Time` entry. Second, there are two different sensors attached to this output. This is because I have both a DHT11 temperature sensor and a BH1750 light sensor attached to the same ESP8266 chip. Finally, my temperature is reported in Celsius.
Hopefully, the Home Assistant definitions will make a little more sense now. `value_json` is just a standard name given to any JSON object ingested by Home Assistant. The format of the `value_template` is `value_json.<component>.<data point>`.
For example, to retrieve the dewpoint:
```
`value_template: '{{ value_json.DHT11.DewPoint}}'`
```
While you can dump this information to a file from within Home Assistant, I use Tasmota's `Console` to see the data it is publishing. (If you want me to do an article on Tasmota, please let me know in the comments below.)
As a side note, I also keep tabs on my local Home Assistant resource usage. To do so, I put this in my sensor.yaml file:
```
 - platform: systemmonitor
    resources:
      - type: disk_use_percent
        arg: /
      - type: memory_free
      - type: memory_use
      - type: processor_use
```
While this is technically not a sensor, I put it here, as I think of it as a data sensor. For more information, see the Home Assistant's [system monitoring][20] documentation.
#### The /config/input_boolean file
This last section is pretty easy to set up, and I use it for a wide variety of applications. An input boolean is used to track the status of something. It's either on or off, home or away, etc. I use these quite extensively in my automations.
My definitions are:
```
   steve_home:
        name: steve
    steve_in_bed:
        name: 'steve in bed'
    guest_home:
   
    kitchen_override:
        name: kitchen
    kitchen_fan_override:
        name: kitchen_fan
    laundryroom_override:
        name: laundryroom
    bathroom_override:
        name: bathroom
    hallway_override:  
        name: hallway
    livingroom_override:  
        name: livingroom
    ensuite_bathroom_override:
        name: ensuite_bathroom
    steve_desk_light_override:
        name: steve_desk_light
    projector_led_override:
        name: projector_led
       
    project_power_status:
        name: 'Projector Power Status'
    tv_power_status:
        name: 'TV Power Status'
    bed_time:
        name: "It's Bedtime"
```
I use some of these directly in the Lovelace UI. I create little badges that I put at the top of each of the pages I have in the UI:
![Home Assistant options in Lovelace UI][21]
(Steve Ovens, [CC BY-SA 4.0][11])
These can be used to determine whether I am home, if a guest is in my house, and so on. Clicking on one of these badges allows me to toggle the boolean, and this object can be read by automations to make decisions about how the “smart devices” react to a person's presence (if at all). I'll revisit the booleans in a future article when I examine Node-RED in more detail.
### Wrapping up
In this article, I looked at the YAML configuration files and added a few custom sensors into the mix. You are well on the way to getting some functioning automation with Home Assistant and Node-RED. In the next article, I'll dive into some basic Node-RED flows and introduce some basic automations.
Stick around; I've got plenty more to cover, and as always, leave a comment below if you would like me to examine something specific. If I can, I'll be sure to incorporate the answers to your questions into future articles.
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/2/home-assistant-custom-sensors
作者:[Steve Ovens][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/stratusss
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/browser_screen_windows_files.png?itok=kLTeQUbY (Computer screen with files or windows open)
[2]: https://opensource.com/article/21/1/home-automation-5-homeassistant-addons
[3]: https://opensource.com/article/20/11/home-assistant
[4]: https://opensource.com/article/20/11/cloud-vs-local-home-automation
[5]: https://opensource.com/article/20/11/home-automation-part-3
[6]: https://opensource.com/article/20/12/home-assistant
[7]: https://tasmota.github.io/docs/
[8]: https://esphome.io/
[9]: https://create.arduino.cc/projecthub/Niv_the_anonymous/esp8266-beginner-tutorial-project-6414c8
[10]: https://opensource.com/sites/default/files/uploads/ha-setup22-file-editor-settings.png (Install File Editor)
[11]: https://creativecommons.org/licenses/by-sa/4.0/
[12]: https://opensource.com/sites/default/files/uploads/ha-setup29-configuration-split-files1.png (Configuration split files)
[13]: https://opensource.com/sites/default/files/uploads/ha-setup28-configuration-yaml.png (Default Home Assistant configuration.yaml)
[14]: https://www.home-assistant.io/docs/mqtt/broker
[15]: https://opensource.com/sites/default/files/uploads/ha-setup23-configuration-yaml2.png (Save icon in Home Assistant config)
[16]: https://opensource.com/sites/default/files/uploads/ha-setup24-new-config-file.png (Create config file)
[17]: https://www.home-assistant.io/integrations/binary_sensor/
[18]: https://www.home-assistant.io/lovelace/
[19]: https://opensource.com/sites/default/files/uploads/ha-setup25-bindary_sensor_card.png (Binary sensor card)
[20]: https://www.home-assistant.io/integrations/systemmonitor
[21]: https://opensource.com/sites/default/files/uploads/ha-setup25-input-booleans.png (Home Assistant options in Lovelace UI)

View File

@@ -1,199 +0,0 @@
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (My open source disaster recovery strategy for the home office)
[#]: via: (https://opensource.com/article/21/2/high-availability-home-office)
[#]: author: (Howard Fosdick https://opensource.com/users/howtech)
My open source disaster recovery strategy for the home office
======
In the remote work era, it's more important than ever to have a disaster
recovery plan for your household infrastructure.
![Person using a laptop][1]
I've worked from home for years, and with the COVID-19 crisis, millions more have joined me. Teachers, accountants, librarians, stockbrokers… you name it, these workers now operate full or part time from their homes. Even after the coronavirus crisis ends, many will continue working at home, at least part time. But what happens when the home worker's computer fails? Whether the device is a smartphone, tablet, laptop, or desktop—and whether the problem is hardware or software—the result might be missed workdays and lots of frustration.
This article explores how to ensure high-availability home computing. Open source software is key. It offers device independence so that home workers can easily move between primary and backup devices. Most importantly, it gives users control of their environment, which is the surest route to high availability. This simple high-availability strategy, based on open source, is easy to modify for your needs.
### Different strategies for different situations
I need to emphasize one point upfront: different job functions require different solutions. Some at-home workers can use smartphones or tablets, while others rely on laptops, and still others require high-powered desktop workstations. Some can tolerate an outage of hours or even days, while others must be available without interruption. Some use company-supplied devices, and others must provide their own. Lastly, some home workers store their data in their company's cloud, while others self-manage their data.
Obviously, no single high-availability strategy fits everyone. My strategy probably isn't "the answer" for you, but I hope it prompts you to think about the challenges involved (if you haven't already) and presents some ideas to help you prepare before disaster strikes.
### Defining high availability
Whatever computing device a home worker uses, high availability (HA) involves five interoperable components:
* Device hardware
* System software
* Communications capability
* Applications
* Data
The HA plan must encompass all five components to succeed. Missing any component causes HA failure.
For example, last night, I worked on a cloud-based spreadsheet. If my communications link had failed and I couldn't access my cloud data, that would stop my work on the project… even if I had all the other HA components available in a backup computer.
Of course, there are exceptions. Say last night's spreadsheet was stored on my local computer. If that device failed, I could have kept working as long as I had a backup computer with my data on it, even if I lacked internet access.
To succeed as a high-availability home worker, you must first identify the components you require for your work. Once you've done that, develop a plan to continue working even if one or more components fails.
#### Duplicate replacement
One approach is to create a _duplicate replacement_. Having the exact same hardware, software, communications, apps, and data available on a backup device guarantees that you can work if your primary fails. This approach is simple, though it might cost more to keep a complete backup on hand.
To economize, you might share computers with your family or flatmates. A _shared backup_ is always more cost-effective than a _dedicated backup_, so long as you have top priority on the shared computer when you need it.
#### Functional replacement
The alternative to duplicate replacement is a _functional replacement_. You substitute a working equivalent for the failed component. Say I'm working from my home laptop and connecting through home WiFi. My internet connection fails. Perhaps I can tether my computer to my phone and use the cell network instead. I achieve HA by replacing one technology with an equivalent.
#### Know your requirements
Beyond the five HA components, be sure to identify any special requirements you have. For example, if mobility is important, you might need to replace a broken laptop with another laptop, not a desktop.
HA means identifying all the functions you need, then ensuring your HA plan covers them all.
### Timing, planning, and testing
You must also define your time frame for recovery. Must you be able to continue your work immediately after a failure? Or do you have the luxury of some downtime during which you can react?
The longer your allowable downtime, the more options you have. For example, if you could miss work for several days, you could simply trot a broken device into a repair shop. No need for a backup.
In this article, by "high availability," I mean getting back to work in very short order after a failure, perhaps less than one hour. This typically requires that you have access to a backup device that is immediately available and ready to go. While there might be occasions when you can recover your primary device in a matter of minutes—for example, by working around a failure or by quickly replacing a defective piece of hardware or software—a backup computer is normally part of the HA plan.
HA requires planning and preparation. "Winging it" doesn't suffice; ensure your backup plan works by testing it beforehand.
For example, say your data resides in the cloud. That data is accessible from anywhere, from any device. That sounds ideal. But what if you forget that there's a small but vital bit of data stored locally on your failed computer? If you can't access that essential data, your HA plan fails. A dry run surfaces problems like this.
### Smartphones as backup
Most of us in software engineering and support use laptops and desktops at home. Smartphones and tablets are useful adjuncts, but they aren't at the core of what we do.
The main reasons are screen size and keyboard. For software work, you can't achieve the same level of productivity with a small screen and touchscreen keypad as you can with a large monitor and physical keyboard.
If you normally use a laptop or desktop and opt for a smartphone or tablet as your backup, test it out beforehand to make sure it suffices. Here's an example of the kind of subtlety that might otherwise trip you up. Most videoconferencing platforms run on both smartphones and laptops or desktops, but their mobile apps can differ in small but important ways. And even when the platform does offer an equivalent experience (the way [Jitsi][2] does, for instance), it can be awkward to share charts, slide decks, and documents, to use a chat feature, and so on, just due to the difference in mobile form factors compared to a big computer screen and a variety of input options.
Smartphones make convenient backup devices because nearly everyone has one. But if you designate yours as your functional replacement, then try using it for work one day to verify that it meets your needs.
### Data accessibility
Data access is vital when your primary device fails. Even if you back up your work data, if a device fails, you also may need credentials for VPN or SSH access, specialized software, or forms of data that might not be stored along with your day-to-day documents and directories. You must ensure that when you design a backup scheme for yourself, you include all important data and store encryption keys and other access information securely.
The best way to keep your work data secure is to use your own service. Running [Nextcloud][3] or [Sparkleshare][4] is easy, and hosting is cheap. Both are automated: files you place in a specially designated directory are synchronized with your server. It's not exactly building your own cloud, but it's a great way to leverage the cloud for your own services. You can make the backup process seamless with tools like [Syncthing, Bacula][5], or [rdiff-backup][6].
Cloud storage enables you to access data from any device at any location, but cloud storage will work only if you have a live communications path to it after a failure event. And not all cloud storage meets the privacy and security specifications for all projects. If your workplace has a cloud backup solution, spend some time learning about the cloud vendor's services and find out what level of availability it promises. Check its track record in achieving it. And be sure to devise an alternate way to access your cloud if your primary communications link fails.
### Local backups
If you store your data on a local device, you'll be responsible for backing it up and recovering it. In that case, back up your data to an alternate device, and verify that you can restore it within your acceptable time frame. This is your _time-to-recovery_.
You'll also need to secure that data and meet any privacy requirements your employer specifies.
#### Acceptable loss
Consider how much data you can afford to lose in the event of an outage. For example, if you back up your data nightly, you could lose up to a maximum of one day's work (all the work completed during the day prior to the nightly backup). This is your _backup data timeliness_.
Open source offers many free applications for local data backup and recovery. Generally, the same applications used for remote backups can also apply to local backup plans, so take a look at the [Advanced Rsync][7] or the [Syncthing tutorial][8] articles here on Opensource.com.
Many prefer a data strategy that combines both cloud and local storage. Store your data locally, and then use the cloud as a backup (rather than working on the cloud). Or do it the other way around (although automating the cloud to push backups to you is more difficult than automating your local machine to push backups to the cloud). Storing your data in two separate locations gives your data _geographical redundancy_, which is useful should either site become unavailable.
With a little forethought, you can devise a simple plan to access your data regardless of any outage.
### My high-availability strategy
As a practical example, I'll describe my own HA approach. My goals are a time to recovery of an hour or less and backup data timeliness within a day.
![High Availability Strategy][9]
(Howard Fosdick, [CC BY-SA 4.0][10])
#### Hardware
I use an Android smartphone for phone calls and audioconferences. I can access a backup phone from another family member if my primary fails.
Unfortunately, my phone's small size and touch keyboard mean I can't use it as my backup computer. Instead, I rely on a few generic desktop computers that have standard, interchangeable parts. You can easily maintain such hardware with this simple [free how-to guide][11]. You don't need any hardware experience.
Open source software makes my multibox strategy affordable. It runs so efficiently that even [10-year-old computers work fine][12] as backups for typical office work. Mine are dual-core desktops with 4GB of RAM and any disk that cleanly verifies. These are so inexpensive that you can often get them for free from recycling centers. (In my [charity work][13], I find that many people give them away as unsuitable for running current proprietary software, but they're actually in perfect working order given a flexible operating system like Linux.)
Another way to economize is to designate another family member's computer for your shared backups.
#### Systems software and apps
Running open source software on top of this generic hardware enables me to achieve several benefits. First, the flexibility of open source software enables me to address any possible software failure. For example, with simple operating system commands, I can copy, move, back up, and recover the operating system, applications, and data across partitions, disks, or computers. I don't have to worry about software constraints, vendor lock-in, proprietary backup file formats, licensing or activation restrictions, or extra fees.
Another open source benefit is that you control your operating system. If you don't have control over your own system, you could be subject to forced restarts, unexpected and unwanted updates, and forced upgrades. My relative has run into such problems more than once. Without his knowledge or consent, his computer suddenly launched a forced upgrade from Windows 7 to Windows 10, which cost him three days of lost income (and untold frustration). The lesson: Your vendor's agenda may not coincide with your own.
All operating systems have bugs. The difference is that open source software doesn't force you to eat them.
#### Data classification
I use very simple techniques to make my data highly available.
I can't use cloud services for my data due to privacy requirements. Instead, my data "master copy" resides on a USB-connected disk. I plug it into any of several computers. After every session, I back up any altered data on the computer I used.
Of course, this approach is only feasible if your backups run quickly. For most home workers, that's easy. All you have to do is segregate your data by size and how frequently you update it.
Isolate big files like photos, audio, and video into separate folders or partitions. Make sure you back up only the files that are new or modified, not older items that have already been backed up.
Much of my work involves office suites. These generate small files, so I isolate each project in its own folder. For example, I stored the two dozen files I used to write this article in a single subdirectory. Backing it up is as simple as copying that folder.
Giving a little thought to data segregation and backing up only modified files ensures quick, easy backups for most home workers. My approach is simple; it works best if you only work on a couple of projects in a session. And I can tolerate losing up to a day's work. You can easily automate a more refined backup scheme for yourself.
For software development, I take an entirely different approach. I use software versioning, which transparently handles all software backup issues for me and coordinates with other developers. My HA planning in this area focuses just on ensuring I can access the online tool.
#### Communications
Like many home users, I communicate through both a cellphone network and the internet. If my internet goes down, I can use the cell network instead by tethering my laptop to my Android smartphone.
### Learning from failure
Using my strategy for 15 years, how have I fared? What failures have I experienced, and how did they turn out?
1. **Motherboard burnout:** One day, my computer wouldn't turn on. I simply moved my USB "master data" external disk to another computer and used that. I lost no data. After some investigation, I determined it was a motherboard failure, so I scrapped the computer and used it for parts.
2. **Drive failure:** An internal disk failed while I was working. I just moved my USB master disk to a backup computer. I lost 10 minutes of data updates. After work, I created a new boot disk by copying one from another computer—flexibility that only open source software offers. I used the affected computer the next day.
3. **Fatal software update:** An update caused a failure in an important login service. I shifted to a backup computer where I hadn't yet applied the fatal update. I lost no data. After work, I searched for help with this problem and had it solved in an hour.
4. **Monitor burnout:** My monitor fizzled out. I just swapped in a backup display and kept working. This took 10 minutes. After work, I determined that the problem was a burned-out capacitor, so I recycled the monitor.
5. **Power outage:** Now, here's a situation I didn't plan for! A tornado took down the electrical power in our entire town for two days. I learned that one should think through _all_ possible contingencies—including alternate work sites.
### Make your plan
If you work from home, you need to consider what will happen when your home computer fails. If not, you could experience frustrating workdays off while you scramble to fix the problem.
Open source software is the key. It runs so efficiently on older, cheaper computers that they become affordable backup machines. It offers device independence, and it ensures that you can design solutions that work best for you.
For most people, ensuring high availability is very simple. The trick is thinking about it in advance. Create a plan _and then test it_.
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/2/high-availability-home-office
作者:[Howard Fosdick][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/howtech
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/laptop_screen_desk_work_chat_text.png?itok=UXqIDRDD (Person using a laptop)
[2]: https://jitsi.org/downloads/
[3]: https://opensource.com/article/20/7/nextcloud
[4]: https://opensource.com/article/19/4/file-sharing-git
[5]: https://opensource.com/article/19/3/backup-solutions
[6]: https://opensource.com/life/16/3/turn-your-old-raspberry-pi-automatic-backup-server
[7]: https://opensource.com/article/19/5/advanced-rsync
[8]: https://opensource.com/article/18/9/take-control-your-data-syncthing
[9]: https://opensource.com/sites/default/files/uploads/my_ha_strategy.png (High Availability Strategy)
[10]: https://creativecommons.org/licenses/by-sa/4.0/
[11]: http://www.rexxinfo.org/Quick_Guide/Quick_Guide_To_Fixing_Computer_Hardware
[12]: https://opensource.com/article/19/7/how-make-old-computer-useful-again
[13]: https://www.freegeekchicago.org/

View File

@@ -1,368 +0,0 @@
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (Configure multi-tenancy with Kubernetes namespaces)
[#]: via: (https://opensource.com/article/21/2/kubernetes-namespaces)
[#]: author: (Mike Calizo https://opensource.com/users/mcalizo)
Configure multi-tenancy with Kubernetes namespaces
======
Namespaces provide basic building blocks of access control for
applications, users, or groups of users.
![shapes of people symbols][1]
Most enterprises want a multi-tenancy platform to run their cloud-native applications because it helps manage resources, costs, and operational efficiency and control [cloud waste][2].
[Kubernetes][3] is the leading open source platform for managing containerized workloads and services. It gained this reputation because of its flexibility in allowing operators and developers to establish automation with declarative configuration. But there is a catch: Because Kubernetes grows rapidly, the old problem of velocity becomes an issue. The bigger your adoption, the more issues and resource waste you discover.
### An example of scale
Imagine your company started small with its Kubernetes adoption by deploying a variety of internal applications. It has multiple project streams running with multiple developers dedicated to each project stream.
In a scenario like this, you need to make sure your cluster administrator has full control over the cluster to manage its resources and implement cluster policy and security standards. In a way, the admin is herding the cluster's users to use best practices. A namespace is very useful in this instance because it enables different teams to share a single cluster where computing resources are subdivided into multiple teams.
While namespaces are your first step to Kubernetes multi-tenancy, they are not good enough on their own. There are a number of Kubernetes primitives you need to consider so that you can administer your cluster properly and put it into a production-ready implementation.
The Kubernetes primitives for multi-tenancy are:
1. **RBAC:** Role-based access control for Kubernetes
2. **Network policies:** To isolate traffic between namespaces
3. **Resource quotas:** To control fair access to cluster resources
This article explores how to use Kubernetes namespaces and some basic RBAC configurations to partition a single Kubernetes cluster and take advantage of this built-in Kubernetes tooling.
### What is a Kubernetes namespace?
Before digging into how to use namespaces to prepare your Kubernetes cluster to become multi-tenant-ready, you need to know what namespaces are.
A [namespace][4] is a Kubernetes object that partitions a Kubernetes cluster into multiple virtual clusters. This is done with the aid of [Kubernetes names and IDs][5]. Namespaces use the Kubernetes name object, which means that each object inside a namespace gets a unique name and ID across the cluster to allow virtual partitioning.
### How namespaces help in multi-tenancy
Namespaces are one of the Kubernetes primitives you can use to partition your cluster into multiple virtual clusters to allow multi-tenancy. Each namespace is isolated from every other user's, team's, or application's namespace. This isolation is essential in multi-tenancy so that updates and changes in applications, users, and teams are contained within the specific namespace. (Note that namespace does not provide network segmentation.)
Before moving ahead, verify the default namespace in a working Kubernetes cluster:
```
[root@master ~]# kubectl get namespace
NAME              STATUS   AGE
default           Active   3d
kube-node-lease   Active   3d
kube-public       Active   3d
kube-system       Active   3d
```
Then create your first namespace, called **test**:
```
[root@master ~]# kubectl create namespace test
namespace/test created
```
Verify the newly created namespace:
```
[root@master ~]# kubectl get namespace
NAME              STATUS   AGE
default           Active   3d
kube-node-lease   Active   3d
kube-public       Active   3d
kube-system       Active   3d
test              Active   10s
[root@master ~]#
```
Describe the newly created namespace:
```
[root@master ~]# kubectl describe namespace test
Name:         test
Labels:       <none>
Annotations:  <none>
Status:       Active
No resource quota.
No LimitRange resource.
```
To delete a namespace:
```
[root@master ~]# kubectl delete namespace test
namespace "test" deleted
```
Your new namespace is active, but it doesn't have any labels, annotations, or quota-limit ranges defined. However, now that you know how to create and describe and delete a namespace, I'll show how you can use a namespace to virtually partition a Kubernetes cluster.
### Partitioning clusters using namespace and RBAC
Deploy the following simple application to learn how to partition a cluster using namespace and isolate an application and its related objects from "other" users.
First, verify the namespace you will use. For simplicity, use the **test** namespace you created above:
```
[root@master ~]# kubectl get namespaces
NAME              STATUS   AGE
default           Active   3d
kube-node-lease   Active   3d
kube-public       Active   3d
kube-system       Active   3d
test              Active   3h
```
Then deploy a simple application called **test-app** inside the test namespace by using the following configuration:
```
apiVersion: v1
kind: Pod
metadata:
  name: test-app                 ⇒ name of the application
  namespace: test                ⇒ the namespace where the app runs
  labels:
     app: test-app                      ⇒ labels for the app
spec:
  containers:
  - name: test-app
    image: nginx:1.14.2         ⇒ the image we used for the app.
    ports:
    - containerPort: 80
```
Deploy it:
```
$ kubectl create -f test-app.yaml
    pod/test-app created
```
Then verify the application pod was created:
```
$ kubectl get pods -n test
  NAME       READY   STATUS    RESTARTS   AGE
  test-app   1/1     Running   0          18s
```
Now that the running application is inside the **test** namespace, test a use case where:
* **auth-user** can edit and view all the objects inside the test namespace
* **un-auth-user** can only view the namespace
I pre-created the users for you to test. If you want to know how I created the users inside Kubernetes, view the commands [here][6].
```
$ kubectl config view -o jsonpath='{.users[*].name}'
  auth-user
  kubernetes-admin
  un-auth-user
```
With this set up, create a Kubernetes [Role and RoleBindings][7] to isolate the target namespace **test** to allow **auth-user** to view and edit objects inside the namespace and not allow **un-auth-user** to access or view the objects inside the **test** namespace.
Start by creating a ClusterRole and a Role. These objects are a list of verbs (action) permitted on specific resources and namespaces.
Create a ClusterRole:
```
$ cat clusterrole.yaml
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
  name: list-deployments
  namespace: test
rules:
  - apiGroups: [ apps ]
    resources: [ deployments ]
    verbs: [ get, list ]
```
Create a Role:
```
$ cat role.yaml
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: Role
metadata:
  name: list-deployments
  namespace: test
rules:
  - apiGroups: [ apps ]
    resources: [ deployments ]
    verbs: [ get, list ]
```
Apply the Role:
```
$ kubectl create -f role.yaml
roles.rbac.authorization.k8s.io "list-deployments" created
```
Use the same command to create a ClusterRole:
```
$ kubectl create -f clusterrole.yaml
$ kubectl get role -n test
  NAME               CREATED AT
  list-deployments   2021-01-18T00:54:00Z
```
Verify the Roles:
```
$ kubectl describe roles -n test
  Name:         list-deployments
  Labels:       <none>
  Annotations:  <none>
  PolicyRule:
    Resources         Non-Resource URLs  Resource Names  Verbs
    ---------         -----------------  --------------  -----
    deployments.apps  []                 []              [get list]
```
Remember that you must create RoleBindings by namespace, not by user. This means you need to create two role bindings for user **auth-user**.
Here are the sample RoleBinding YAML files to permit **auth-user** to edit and view.
**To edit:**
```
$ cat rolebinding-auth-edit.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: auth-user-edit
  namespace: test
subjects:
\- kind: User
  name: auth-user
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: edit
  apiGroup: rbac.authorization.k8s.io
```
**To view:**
```
$ cat rolebinding-auth-view.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: auth-user-view
  namespace: test
subjects:
\- kind: User
  name: auth-user
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: view
  apiGroup: rbac.authorization.k8s.io
```
Create these YAML files:
```
$ kubectl create rolebinding-auth-view.yaml
$ kubectl create rolebinding-auth-edit.yaml
```
Verify if the RoleBindings were successfully created:
```
$ kubectl get rolebindings -n test
NAME             ROLE               AGE
auth-user-edit   ClusterRole/edit   48m
auth-user-view   ClusterRole/view   47m
```
With the requirements set up, test the cluster partitioning:
```
[root@master]$ sudo su un-auth-user
[un-auth-user@master ~]$ kubect get pods -n test
[un-auth-user@master ~]$ kubectl get pods -n test
Error from server (Forbidden): pods is forbidden: User "un-auth-user" cannot list resource "pods" in API group "" in the namespace "test"
```
Log in as **auth-user**:
```
[root@master ]# sudo su auth-user
[auth-user@master auth-user]$ kubectl get pods -n test
NAME       READY   STATUS    RESTARTS   AGE
test-app   1/1     Running   0          3h8m
[auth-user@master un-auth-user]$
[auth-user@master auth-user]$ kubectl edit pods/test-app -n test
Edit cancelled, no changes made.
```
You can view and edit the objects inside the **test** namespace. How about viewing the cluster nodes?
```
[auth-user@master auth-user]$ kubectl get nodes
Error from server (Forbidden): nodes is forbidden: User "auth-user" cannot list resource "nodes" in API group "" at the cluster scope
[auth-user@master auth-user]$
```
You can't because the role bindings for user **auth-user** dictate they have access to view or edit objects only inside the **test** namespace.
### Enable access control with namespaces
Namespaces provide basic building blocks of access control using RBAC and isolation for applications, users, or groups of users. But using namespaces alone as your multi-tenancy solution is not enough in an enterprise implementation. It is recommended that you use other Kubernetes multi-tenancy primitives to attain further isolation and implement proper security.
Namespaces can provide some basic isolation in your Kubernetes cluster; therefore, it is important to consider them upfront, especially when planning a multi-tenant cluster. Namespaces also allow you to logically segregate and assign resources to individual users, teams, or applications.
By using namespaces, you can increase resource efficiencies by enabling a single cluster to be used for a diverse set of workloads.
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/2/kubernetes-namespaces
作者:[Mike Calizo][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/mcalizo
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/Open%20Pharma.png?itok=GP7zqNZE (shapes of people symbols)
[2]: https://devops.com/the-cloud-is-booming-but-so-is-cloud-waste/
[3]: https://opensource.com/resources/what-is-kubernetes
[4]: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/
[5]: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/
[6]: https://www.adaltas.com/en/2019/08/07/users-rbac-kubernetes/
[7]: https://kubernetes.io/docs/reference/access-authn-authz/rbac/

View File

@@ -1,354 +0,0 @@
[#]: subject: "Draw Mandelbrot fractals with GIMP scripting"
[#]: via: "https://opensource.com/article/21/2/gimp-mandelbrot"
[#]: author: "Cristiano L. Fontana https://opensource.com/users/cristianofontana"
[#]: collector: "lkxed"
[#]: translator: " "
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
Draw Mandelbrot fractals with GIMP scripting
======
Create complex mathematical images with GIMP's Script-Fu language.
![Painting art on a computer screen][1]
Image by: Opensource.com
The GNU Image Manipulation Program ([GIMP][2]) is my go-to solution for image editing. Its toolset is very powerful and convenient, except for doing [fractals][3], which is one thing you cannot draw by hand easily. These are fascinating mathematical constructs that have the characteristic of being [self-similar][4]. In other words, if they are magnified in some areas, they will look remarkably similar to the unmagnified picture. Besides being interesting, they also make very pretty pictures!
![Rotated and magnified portion of the Mandelbrot set using Firecode][5]
GIMP can be automated with [Script-Fu][6] to do [batch processing of images][7] or create complicated procedures that are not practical to do by hand; drawing fractals falls in the latter category. This tutorial will show how to draw a representation of the [Mandelbrot fractal][8] using GIMP and Script-Fu.
![Mandelbrot set drawn using GIMP's Firecode palette][9]
![Rotated and magnified portion of the Mandelbrot set using Firecode.][10]
In this tutorial, you will write a script that creates a layer in an image and draws a representation of the Mandelbrot set with a colored environment around it.
### What is the Mandelbrot set?
Do not panic! I will not go into too much detail here. For the more math-savvy, the Mandelbrot set is defined as the set of [complex numbers][11] *a* for which the succession
zn+1 = zn2 + a
does not diverge when starting from *z₀ = 0*.
In reality, the Mandelbrot set is the fancy-looking black blob in the pictures; the nice-looking colors are outside the set. They represent how many iterations are required for the magnitude of the succession of numbers to pass a threshold value. In other words, the color scale shows how many steps are required for the succession to pass an upper-limit value.
### GIMP's Script-Fu
[Script-Fu][12] is the scripting language built into GIMP. It is an implementation of the [Scheme programming language][13].
If you want to get more acquainted with Scheme, GIMP's documentation offers an [in-depth tutorial][14]. I also wrote an article about [batch processing images][15] using Script-Fu. Finally, the Help menu offers a Procedure Browser with very extensive documentation with all of Script-Fu's functions described in detail.
![GIMP Procedure Browser][16]
Scheme is a Lisp-like language, so a major characteristic is that it uses a [prefix notation][17] and a [lot of parentheses][18]. Functions and operators are applied to a list of operands by prefixing them:
```
(function-name operand operand ...)
(+ 2 3)
↳ Returns 5
(list 1 2 3 5)
↳ Returns a list containing 1, 2, 3, and 5
```
### Write the script
You can write your first script and save it to the **Scripts** folder found in the preferences window under **Folders → Scripts**. Mine is at `$HOME/.config/GIMP/2.10/scripts`. Write a file called `mandelbrot.scm` with:
```
; Complex numbers implementation
(define (make-rectangular x y) (cons x y))
(define (real-part z) (car z))
(define (imag-part z) (cdr z))
(define (magnitude z)
  (let ((x (real-part z))
        (y (imag-part z)))
    (sqrt (+ (* x x) (* y y)))))
(define (add-c a b)
  (make-rectangular (+ (real-part a) (real-part b))
                    (+ (imag-part a) (imag-part b))))
(define (mul-c a b)
  (let ((ax (real-part a))
        (ay (imag-part a))
        (bx (real-part b))
        (by (imag-part b)))
    (make-rectangular (- (* ax bx) (* ay by))
                      (+ (* ax by) (* ay bx)))))
; Definition of the function creating the layer and drawing the fractal
(define (script-fu-mandelbrot image palette-name threshold domain-width domain-height offset-x offset-y)
  (define num-colors (car (gimp-palette-get-info palette-name)))
  (define colors (cadr (gimp-palette-get-colors palette-name)))
  (define width (car (gimp-image-width image)))
  (define height (car (gimp-image-height image)))
  (define new-layer (car (gimp-layer-new image
                                         width height
                                         RGB-IMAGE
                                         "Mandelbrot layer"
                                         100
                                         LAYER-MODE-NORMAL)))
  (gimp-image-add-layer image new-layer 0)
  (define drawable new-layer)
  (define bytes-per-pixel (car (gimp-drawable-bpp drawable)))
  ; Fractal drawing section.
  ; Code from: https://rosettacode.org/wiki/Mandelbrot_set#Racket
  (define (iterations a z i)
    (let ((z (add-c (mul-c z z) a)))
       (if (or (= i num-colors) (> (magnitude z) threshold))
          i
          (iterations a z (+ i 1)))))
  (define (iter->color i)
    (if (>= i num-colors)
        (list->vector '(0 0 0))
        (list->vector (vector-ref colors i))))
  (define z0 (make-rectangular 0 0))
  (define (loop x end-x y end-y)
    (let* ((real-x (- (* domain-width (/ x width)) offset-x))
           (real-y (- (* domain-height (/ y height)) offset-y))
           (a (make-rectangular real-x real-y))
           (i (iterations a z0 0))
           (color (iter->color i)))
      (cond ((and (< x end-x) (< y end-y)) (gimp-drawable-set-pixel drawable x y bytes-per-pixel color)
                                           (loop (+ x 1) end-x y end-y))
            ((and (>= x end-x) (< y end-y)) (gimp-progress-update (/ y end-y))
                                            (loop 0 end-x (+ y 1) end-y)))))
  (loop 0 width 0 height)
  ; These functions refresh the GIMP UI, otherwise the modified pixels would be evident
  (gimp-drawable-update drawable 0 0 width height)
  (gimp-displays-flush)
)
(script-fu-register
  "script-fu-mandelbrot"          ; Function name
  "Create a Mandelbrot layer"     ; Menu label
                                  ; Description
  "Draws a Mandelbrot fractal on a new layer. For the coloring it uses the palette identified by the name provided as a string. The image boundaries are defined by its domain width and height, which correspond to the image width and height respectively. Finally the image is offset in order to center the desired feature."
  "Cristiano Fontana"             ; Author
  "2021, C.Fontana. GNU GPL v. 3" ; Copyright
  "27th Jan. 2021"                ; Creation date
  "RGB"                           ; Image type that the script works on
  ;Parameter    Displayed            Default
  ;type         label                values
  SF-IMAGE      "Image"              0
  SF-STRING     "Color palette name" "Firecode"
  SF-ADJUSTMENT "Threshold value"    '(4 0 10 0.01 0.1 2 0)
  SF-ADJUSTMENT "Domain width"       '(3 0 10 0.1 1 4 0)
  SF-ADJUSTMENT "Domain height"      '(3 0 10 0.1 1 4 0)
  SF-ADJUSTMENT "X offset"           '(2.25 -20 20 0.1 1 4 0)
  SF-ADJUSTMENT "Y offset"           '(1.50 -20 20 0.1 1 4 0)
)
(script-fu-menu-register "script-fu-mandelbrot" "<Image>/Layer/")
```
I will go through the script to show you what it does.
### Get ready to draw the fractal
Since this image is all about complex numbers, I wrote a quick and dirty implementation of complex numbers in Script-Fu. I defined the complex numbers as [pairs][19] of real numbers. Then I added the few functions needed for the script. I used [Racket's documentation][20] as inspiration for function names and roles:
```
(define (make-rectangular x y) (cons x y))
(define (real-part z) (car z))
(define (imag-part z) (cdr z))
(define (magnitude z)
  (let ((x (real-part z))
        (y (imag-part z)))
    (sqrt (+ (* x x) (* y y)))))
(define (add-c a b)
  (make-rectangular (+ (real-part a) (real-part b))
                    (+ (imag-part a) (imag-part b))))
(define (mul-c a b)
  (let ((ax (real-part a))
        (ay (imag-part a))
        (bx (real-part b))
        (by (imag-part b)))
    (make-rectangular (- (* ax bx) (* ay by))
                      (+ (* ax by) (* ay bx)))))
```
### Draw the fractal
The new function is called `script-fu-mandelbrot`. The best practice for writing a new function is to call it `script-fu-something` so that it can be identified in the Procedure Browser easily. The function requires a few parameters: an `image` to which it will add a layer with the fractal, the `palette-name` identifying the color palette to be used, the `threshold` value to stop the iteration, the `domain-width` and `domain-height` that identify the image boundaries, and the `offset-x` and `offset-y` to center the image to the desired feature. The script also needs some other parameters that it can deduce from the GIMP interface:
```
(define (script-fu-mandelbrot image palette-name threshold domain-width domain-height offset-x offset-y)
  (define num-colors (car (gimp-palette-get-info palette-name)))
  (define colors (cadr (gimp-palette-get-colors palette-name)))
  (define width (car (gimp-image-width image)))
  (define height (car (gimp-image-height image)))
  ...
```
Then it creates a new layer and identifies it as the script's `drawable`. A "drawable" is the element you want to draw on:
```
(define new-layer (car (gimp-layer-new image
                                       width height
                                       RGB-IMAGE
                                       "Mandelbrot layer"
                                       100
                                       LAYER-MODE-NORMAL)))
(gimp-image-add-layer image new-layer 0)
(define drawable new-layer)
(define bytes-per-pixel (car (gimp-drawable-bpp drawable)))
```
For the code determining the pixels' color, I used the [Racket][21] example on the [Rosetta Code][22] website. It is not the most optimized algorithm, but it is simple to understand. Even a non-mathematician like me can understand it. The `iterations` function determines how many steps the succession requires to pass the threshold value. To cap the iterations, I am using the number of colors in the palette. In other words, if the threshold is too high or the succession does not grow, the calculation stops at the `num-colors` value. The `iter->color` function transforms the number of iterations into a color using the provided palette. If the iteration number is equal to `num-colors`, it uses black because this means that the succession is probably bound and that pixel is in the Mandelbrot set:
```
; Fractal drawing section.
; Code from: https://rosettacode.org/wiki/Mandelbrot_set#Racket
(define (iterations a z i)
  (let ((z (add-c (mul-c z z) a)))
     (if (or (= i num-colors) (> (magnitude z) threshold))
        i
        (iterations a z (+ i 1)))))
(define (iter->color i)
  (if (>= i num-colors)
      (list->vector '(0 0 0))
      (list->vector (vector-ref colors i))))
```
Because I have the feeling that Scheme users do not like to use loops, I implemented the function looping over the pixels as a recursive function. The `loop` function reads the starting coordinates and their upper boundaries. At each pixel, it defines some temporary variables with the `let*` function: `real-x` and `real-y` are the real coordinates of the pixel in the complex plane, according to the parameters; the `a` variable is the starting point for the succession; the `i` is the number of iterations; and finally `color` is the pixel color. Each pixel is colored with the `gimp-drawable-set-pixel` function that is an internal GIMP procedure. The peculiarity is that it is not undoable, and it does not trigger the image to refresh. Therefore, the image will not be updated during the operation. To play nice with the user, at the end of each row of pixels, it calls the `gimp-progress-update` function, which updates a progress bar in the user interface:
```
(define z0 (make-rectangular 0 0))
(define (loop x end-x y end-y)
  (let* ((real-x (- (* domain-width (/ x width)) offset-x))
         (real-y (- (* domain-height (/ y height)) offset-y))
         (a (make-rectangular real-x real-y))
         (i (iterations a z0 0))
         (color (iter->color i)))
    (cond ((and (< x end-x) (< y end-y)) (gimp-drawable-set-pixel drawable x y bytes-per-pixel color)
                                         (loop (+ x 1) end-x y end-y))
          ((and (>= x end-x) (< y end-y)) (gimp-progress-update (/ y end-y))
                                          (loop 0 end-x (+ y 1) end-y)))))
(loop 0 width 0 height)
```
At the calculation's end, the function needs to inform GIMP that it modified the `drawable`, and it should refresh the interface because the image is not "automagically" updated during the script's execution:
```
(gimp-drawable-update drawable 0 0 width height)
(gimp-displays-flush)
```
### Interact with the user interface
To use the `script-fu-mandelbrot` function in the graphical user interface (GUI), the script needs to inform GIMP. The `script-fu-register` function informs GIMP about the parameters required by the script and provides some documentation:
```
(script-fu-register
  "script-fu-mandelbrot"          ; Function name
  "Create a Mandelbrot layer"     ; Menu label
                                  ; Description
  "Draws a Mandelbrot fractal on a new layer. For the coloring it uses the palette identified by the name provided as a string. The image boundaries are defined by its domain width and height, which correspond to the image width and height respectively. Finally the image is offset in order to center the desired feature."
  "Cristiano Fontana"             ; Author
  "2021, C.Fontana. GNU GPL v. 3" ; Copyright
  "27th Jan. 2021"                ; Creation date
  "RGB"                           ; Image type that the script works on
  ;Parameter    Displayed            Default
  ;type         label                values
  SF-IMAGE      "Image"              0
  SF-STRING     "Color palette name" "Firecode"
  SF-ADJUSTMENT "Threshold value"    '(4 0 10 0.01 0.1 2 0)
  SF-ADJUSTMENT "Domain width"       '(3 0 10 0.1 1 4 0)
  SF-ADJUSTMENT "Domain height"      '(3 0 10 0.1 1 4 0)
  SF-ADJUSTMENT "X offset"           '(2.25 -20 20 0.1 1 4 0)
  SF-ADJUSTMENT "Y offset"           '(1.50 -20 20 0.1 1 4 0)
)
```
Then the script tells GIMP to put the new function in the Layer menu with the label "Create a Mandelbrot layer":
```
(script-fu-menu-register "script-fu-mandelbrot" "<Image>/Layer/")
```
Having registered the function, you can visualize it in the Procedure Browser.
![script-fu-mandelbrot function][23]
### Run the script
Now that the function is ready and registered, you can draw the Mandelbrot fractal! First, create a square image and run the script from the Layers menu.
![script running][24]
The default values are a good starting set to obtain the following image. The first time you run the script, create a very small image (e.g., 60x60 pixels) because this implementation is slow! It took several hours for my computer to create the following image in full 1920x1920 pixels. As I mentioned earlier, this is not the most optimized algorithm; rather, it was the easiest for me to understand.
![Mandelbrot set drawn using GIMP's Firecode palette][25]
### Learn more
This tutorial showed how to use GIMP's built-in scripting features to draw an image created with an algorithm. These images show GIMP's powerful set of tools that can be used for artistic applications and mathematical images.
If you want to move forward, I suggest you look at the official documentation and its [tutorial][26]. As an exercise, try modifying this script to draw a [Julia set][27], and please share the resulting image in the comments.
Image by: Rotated and magnified portion of the Mandelbrot set using Firecode. (Cristiano Fontana, CC BY-SA 4.0)
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/2/gimp-mandelbrot
作者:[Cristiano L. Fontana][a]
选题:[lkxed][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/cristianofontana
[b]: https://github.com/lkxed
[1]: https://opensource.com/sites/default/files/lead-images/painting_computer_screen_art_design_creative.png
[2]: https://www.gimp.org/
[3]: https://en.wikipedia.org/wiki/Fractal
[4]: https://en.wikipedia.org/wiki/Self-similarity
[5]: https://opensource.com/sites/default/files/uploads/mandelbrot_portion.png
[6]: https://docs.gimp.org/en/gimp-concepts-script-fu.html
[7]: https://opensource.com/article/21/1/gimp-scripting
[8]: https://en.wikipedia.org/wiki/Mandelbrot_set
[9]: https://opensource.com/sites/default/files/uploads/mandelbrot.png
[10]: https://opensource.com/sites/default/files/uploads/mandelbrot_portion2.png
[11]: https://en.wikipedia.org/wiki/Complex_number
[12]: https://docs.gimp.org/en/gimp-concepts-script-fu.html
[13]: https://en.wikipedia.org/wiki/Scheme_(programming_language)
[14]: https://docs.gimp.org/en/gimp-using-script-fu-tutorial.html
[15]: https://opensource.com/article/21/1/gimp-scripting
[16]: https://opensource.com/sites/default/files/uploads/procedure_browser_0.png
[17]: https://en.wikipedia.org/wiki/Polish_notation
[18]: https://xkcd.com/297/
[19]: https://www.gnu.org/software/guile/manual/html_node/Pairs.html
[20]: https://docs.racket-lang.org/reference/generic-numbers.html?q=make-rectangular#%28part._.Complex_.Numbers%29
[21]: https://racket-lang.org/
[22]: https://rosettacode.org/wiki/Mandelbrot_set#Racket
[23]: https://opensource.com/sites/default/files/uploads/mandelbrot_documentation.png
[24]: https://opensource.com/sites/default/files/uploads/script_working.png
[25]: https://opensource.com/sites/default/files/uploads/mandelbrot.png
[26]: https://docs.gimp.org/en/gimp-using-script-fu-tutorial.html
[27]: https://en.wikipedia.org/wiki/Julia_set

View File

@@ -1,92 +0,0 @@
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (Getting to Know the Cryptocurrency Open Patent Alliance (COPA))
[#]: via: (https://www.linux.com/news/getting-to-know-the-cryptocurrency-open-patent-alliance-copa/)
[#]: author: (Linux.com Editorial Staff https://www.linux.com/author/linuxdotcom/)
Getting to Know the Cryptocurrency Open Patent Alliance (COPA)
======
### ![][1]
### Why is there a need for a patent protection alliance for cryptocurrency technologies?
With the recent surge in popularity of cryptocurrencies and related technologies, Square felt an industry group was needed to protect against litigation and other threats against core cryptocurrency technology and ensure the ecosystem remains vibrant and open for developers and companies.
The same way [Open Invention Network][2] (OIN) and [LOT Network][3] add a layer of patent protection to inter-company collaboration on open source technologies, COPA aims to protect open source cryptocurrency technology. Feeling safe from the threat of lawsuits is a precursor to good collaboration.
* Locking up foundational cryptocurrency technologies in patents stifles innovation and adoption of cryptocurrency in novel and useful applications.
* The offensive use of patents threatens the growth and free availability of cryptocurrency technologies. Many smaller companies and developers do not own patents and cannot deter or defend threats adequately.
By joining COPA, a member can feel secure it can innovate in the cryptocurrency space without fear of litigation between other members. 
### What is Squares involvement in COPA?
Squares core purpose is economic empowerment, and they see cryptocurrency as a core technological pillar. Square helped start and fund COPA with the hope that by encouraging innovation in the cryptocurrency space, more useful ideas and products would get created. COPA management has now diversified to an independent board of technology and regulatory experts, and Square maintains a minority presence.
### Do we need cryptocurrency patents to join COPA? 
No! Anyone can join and benefit from being a member of COPA, regardless of whether they have patents or not. There is no barrier to entry members can be individuals, start-ups, small companies, or large corporations. Here is how COPA works:
* First, COPA members pledge never to use their crypto-technology patents against anyone, except for defensive reasons, effectively making their patents freely available for all.
* Second, members pool all of their crypto-technology patents together to form a shared patent library, which provides a forum to allow members to reasonably negotiate lending patents to one another for defensive purposes.
* The patent pledge and the shared patent library work in tandem to help drive down the incidence and threat of patent litigation, benefiting the cryptocurrency community as a whole. 
* Additionally, COPA monitors core technologies and entities that support cryptocurrency and does its best to research and help address litigation threats against community members.
### What types of companies should join COPA?
* Financial services companies and technology companies working in regulated industries that use distributed ledger or cryptocurrency technology
* Companies or individuals who are interested in collaborating on developing cryptocurrency products or who hold substantial investments in cryptocurrency
### What companies have joined COPA so far?
* Square, Inc.
* Blockchain Commons
* Carnes Validadas
* Request Network
* Foundation Devices
* ARK
* SatoshiLabs
* Transparent Systems
* Horizontal Systems
* VerifyChain
* Blockstack
* Protocol Labs
* Cloudeya Ltd.
* Mercury Cash
* Bithyve
* Coinbase
* Blockstream
* Stakenet
### How to join
Please express interest and get access to our membership agreement here: <https://opencrypto.org/joining-copa/>
--------------------------------------------------------------------------------
via: https://www.linux.com/news/getting-to-know-the-cryptocurrency-open-patent-alliance-copa/
作者:[Linux.com Editorial Staff][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.linux.com/author/linuxdotcom/
[b]: https://github.com/lujun9972
[1]: https://www.linux.com/wp-content/uploads/2021/02/copa-linuxdotcom.jpg
[2]: https://openinventionnetwork.com/
[3]: https://lotnet.com/

View File

@@ -1,115 +0,0 @@
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (Unikraft: Pushing Unikernels into the Mainstream)
[#]: via: (https://www.linux.com/featured/unikraft-pushing-unikernels-into-the-mainstream/)
[#]: author: (Linux.com Editorial Staff https://www.linux.com/author/linuxdotcom/)
Unikraft: Pushing Unikernels into the Mainstream
======
![][1]
Unikernels have been around for many years and are famous for providing excellent performance in boot times, throughput, and memory consumption, to name a few metrics [1]. Despite their apparent potential, unikernels have not yet seen a broad level of deployment due to three main drawbacks:
* **Hard to build**: Putting a unikernel image together typically requires expert, manual work that needs redoing for each application. Also, many unikernel projects are not, and dont aim to be, POSIX compliant, and so significant porting effort is required to have standard applications and frameworks run on them.
* **Hard to extract high performance**: Unikernel projects dont typically expose high-performance APIs; extracting high performance often requires expert knowledge and modifications to the code.
* **Little or no tool ecosystem**: Assuming you have an image to run, deploying it and managing it is often a manual operation. There is little integration with major DevOps or orchestration frameworks.
While not all unikernel projects suffer from all of these issues (e.g., some provide some level of POSIX compliance but the performance is lacking, others target a single programming language and so are relatively easy to build but their applicability is limited), we argue that no single project has been able to successfully address all of them, hindering any significant level of deployment. For the past three years, Unikraft ([www.unikraft.org][2]), a Linux Foundation project under the Xen Projects auspices, has had the explicit aim to change this state of affairs to bring unikernels into the mainstream. 
If youre interested, read on, and please be sure to check out:
* The [replay of our two FOSDEM talks][3] [2,3] and the [virtual stand ][4]
* Our website (unikraft.org) and source code (<https://github.com/unikraft>).
* Our upcoming source code release, 0.5 Tethys (more information at <http://www.unikraft.org/release/>)
* [unikraft.io][5], for industrial partners interested in Unikraft PoCs (or [info@unikraft.io][6])
### High Performance
To provide developers with the ability to obtain high performance easily, Unikraft exposes a set of composable, performance-oriented APIs. The figure below shows Unikrafts architecture: all components are libraries with their own **Makefile** and **Kconfig** configuration files, and so can be added to the unikernel build independently of each other.
![][7]
**Figure 1. Unikraft s fully modular architecture showing high-performance APIs**
APIs are also micro-libraries that can be easily enabled or disabled via a Kconfig menu; Unikraft unikernels can compose which APIs to choose to best cater to an applications needs. For example, an RCP-style application might turn off the **uksched** API (➃ in the figure) to implement a high performance, run-to-completion event loop; similarly, an application developer can easily select an appropriate memory allocator (➅) to obtain maximum performance, or to use multiple different ones within the same unikernel (e.g., a simple, fast memory allocator for the boot code, and a standard one for the application itself). 
![][8] | ![][9]
---|---
**Figure 2. Unikraft memory consumption vs. other unikernel projects and Linux** | **Figure 3. Unikraft NGINX throughput versus other unikernels, Docker, and Linux/KVM.**
 
These APIs, coupled with the fact that all Unikrafts components are fully modular, results in high performance. Figure 2, for instance, shows Unikraft having lower memory consumption than other unikernel projects (HermiTux, Rump, OSv) and Linux (Alpine); and Figure 3 shows that Unikraft outperforms them in terms of NGINX requests per second, reaching 90K on a single CPU core.
Further, we are working on (1) a performance profiler tool to be able to quickly identify potential bottlenecks in Unikraft images and (2) a performance test tool that can automatically run a large set of performance experiments, varying different configuration options to figure out optimal configurations.
### Ease of Use, No Porting Required
Forcing users to port applications to a unikernel to obtain high performance is a showstopper. Arguably, a system is only as good as the applications (or programming languages, frameworks, etc.) can run. Unikraft aims to achieve good POSIX compatibility; one way of doing so is supporting a **libc** (e.g., **musl)**, along with a large set of Linux syscalls. 
![][10]
**Figure 4. Only a certain percentage of syscalls are needed to support a wide range of applications**
While there are over 300 of these, many of them are not needed to run a large set of applications; as shown in Figure 1 (taken from [5]). Having in the range of 145, for instance, is enough to support 50% of all libraries and applications in a Ubuntu distribution (many of which are irrelevant to unikernels, such as desktop applications). As of this writing, Unikraft supports over 130 syscalls and a number of mainstream applications (e.g., SQLite, Nginx, Redis), programming languages and runtime environments such as C/C++, Go, Python, Ruby, Web Assembly, and Lua, not to mention several different hypervisors (KVM, Xen, and Solo5) and ARM64 bare-metal support.
### Ecosystem and DevOps
Another apparent downside of unikernel projects is the almost total lack of integration with existing, major DevOps and orchestration frameworks. Working towards the goal of integration, in the past year, we created the **kraft** tool, allowing users to choose an application and a target platform simply (e.g., KVM on x86_64) and take care of building the image running it.
Beyond this, we have several sub-projects ongoing to support in the coming months:
* **Kubernetes**: If youre already using Kubernetes in your deployments, this work will allow you to deploy much leaner, fast Unikraft images _transparently._
* **Cloud Foundry**: Similarly, users relying on Cloud Foundry will be able to generate Unikraft images through it, once again transparently.
* **Prometheus**: Unikernels are also notorious for having very primitive or no means for monitoring running instances. Unikraft is targeting Prometheus support to provide a wide range of monitoring capabilities. 
In all, we believe Unikraft is getting closer to bridging the gap between unikernel promise and actual deployment. We are very excited about this years upcoming features and developments, so please feel free to drop us a line if you have any comments, questions, or suggestions at [**info@unikraft.io**][6].
_**About the author: [Dr. Felipe Huici][11] is Chief Researcher, Systems and Machine Learning Group, NEC Laboratories Europe GmbH**_
### References
[1] Unikernels Rethinking Cloud Infrastructure. <http://unikernel.org/>
[2] Is the Time Ripe for Unikernels to Become Mainstream with Unikraft? FOSDEM 2021 Microkernel developer room. <https://fosdem.org/2021/schedule/event/microkernel_unikraft/>
[3] Severely Debloating Cloud Images with Unikraft. FOSDEM 2021 Virtualization and IaaS developer room. <https://fosdem.org/2021/schedule/event/vai_cloud_images_unikraft/>
[4] Welcome to the Unikraft Stand! <https://stands.fosdem.org/stands/unikraft/>
[5] A study of modern Linux API usage and compatibility: what to support when youre supporting. Eurosys 2016. <https://dl.acm.org/doi/10.1145/2901318.2901341>
--------------------------------------------------------------------------------
via: https://www.linux.com/featured/unikraft-pushing-unikernels-into-the-mainstream/
作者:[Linux.com Editorial Staff][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.linux.com/author/linuxdotcom/
[b]: https://github.com/lujun9972
[1]: https://www.linux.com/wp-content/uploads/2021/02/unikraft.svg
[2]: http://www.unikraft.org
[3]: https://video.fosdem.org/2021/stands/unikraft/
[4]: https://stands.fosdem.org/stands/unikraft/
[5]: http://www.unikraft.io
[6]: mailto:info@unikraft.io
[7]: https://www.linux.com/wp-content/uploads/2021/02/unikraft1.png
[8]: https://www.linux.com/wp-content/uploads/2021/02/unikraft2.png
[9]: https://www.linux.com/wp-content/uploads/2021/02/unikraft3.png
[10]: https://www.linux.com/wp-content/uploads/2021/02/unikraft4.png
[11]: https://www.linkedin.com/in/felipe-huici-47a559127/

View File

@@ -1,222 +0,0 @@
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (Installing Nextcloud 20 on Fedora Linux with Podman)
[#]: via: (https://fedoramagazine.org/nextcloud-20-on-fedora-linux-with-podman/)
[#]: author: (dschier https://fedoramagazine.org/author/danielwtd/)
Installing Nextcloud 20 on Fedora Linux with Podman
======
![][1]
Nowadays, many open source projects offer container images for easy deployment. This is very handy when running a home server or lab environment. A previous Fedora Magazine article covered [installing Nextcloud from the source package][2]. This article explains how you can run Nextcloud on Fedora 33 as a container deployment with Podman.
### What is Nextcloud?
[Nextcloud][3] started in 2016 as a fork of Owncloud. Since then, it evolved into a full-fledged collaboration software offering file-, calendar-, and contact-syncing, plus much more. You can run a simple Kanban Board in it or write documents collaboratively. Nextcloud is fully open source under the AGPLv3 License and can be used for private or commercial use alike.
### What is Podman?
Podman is a container engine for developing, managing, and running OCI Containers on your Linux System. It offers a wide variety of features like rootless mode, cgroupv2 support, pod management, and it can run daemonless. Furthermore, you are getting a Docker compatible API for further development. It is available by default on Fedora Workstation and ready to be used.
In case you need to install podman, run:
```
sudo dnf install podman
```
### Designing the Deployment
Every deployment needs a bit of preparation. Sure, you can simply start a container and start using it, but that wouldnt be so much fun. A well-thought and designed deployment should be easy to understand and offer some kind of flexibility.
#### Container / Images
First, you need to choose the proper container images for the deployment. This is quite easy for Nextcloud, since it offers already a pretty good documentation for container deployments. Nextcloud supports two variations: Nextcloud Apache httpd (which is fully self-contained) and Nextcloud php-fpm (which needs an additional nginx container).
In both cases, you also need to provide a database, which can be MariaDB (recommended) or PostgreSQL (also supported). This article uses the Apache httpd + MariaDB installation.
#### Volumes
Running a container does not persist data you create during the runtime. You perform updates by recreating the container. Therefore, you will need some volumes for the database and the Nextcloud files. Nextcloud also recommends you put the “data” folder in a separate volume. So you will end up with three volumes:
* nextcloud-app
* nextcloud-data
* nextcloud-db
#### Network
Lastly, you need to consider networking. One of the benefits of containers is that you can re-create your deployment as it may look like in production. [Network segmentation][4] is a very common practice and should be considered for a container deployment, too. This tutorial will not add advanced features like network load balancing or security segmentation. You will need only one network which you will use to publish the ports for Nextcloud. Creating a network also provides the dnsname plugin, which will allow container communication based on container names.
#### The picture
Now that every single element is prepared, you can put these together and get a really nice understanding of how the development will look.
![][5]
### Run, Nextcloud, Run
Now you have prepared all of the ingredients and you can start running the commands to deploy Nextcloud. All commands can be used for root-privileged or rootless deployments. This article will stick to rootless deployments.
Sart with the network:
```
# Creating a new network
$ podman network create nextcloud-net
# Listing all networks
$ podman network ls
# Inspecting a network
$ podman network inspect nextcloud-net
```
As you can see in the last command, you created a DNS zone with the name “dns.podman”. All containers created in this network are reachable via “CONTAINER_NAME.dns.podman”.
Next, optionally prepare your volumes. This step can be skipped, since Podman will create named volumes on demand, if they do not exist. Podman supports named volumes, which it creates in special locations, so you dont need to take care of SELinux or alike.
```
# Creating the volumes
$ podman volume create nextcloud-app
$ podman volume create nextcloud-data
$ podman volume create nextcloud-db
# Listing volumes
$ podman volume ls
# Inspecting volumes (this also provides the full path)
$ podman volume inspect nextcloud-app
```
Network and volumes are done. Now provide the containers.
First, you need the database. According to the MariaDB image documentation, you need to provide some additional environment variables,. Additionally, you need to attach the created volume, connect the network, and provide a name for the container. Most of the values will be needed in the next commands again. (Note that you should replace DB_USER_PASSWORD and DB_ROOT_PASSWORD with unique passwords.)
```
# Deploy Mariadb
$ podman run --detach
--env MYSQL_DATABASE=nextcloud
--env MYSQL_USER=nextcloud
--env MYSQL_PASSWORD=DB_USER_PASSWORD
--env MYSQL_ROOT_PASSWORD=DB_ROOT_PASSWORD
--volume nextcloud-db:/var/lib/mysql
--network nextcloud-net
--restart on-failure
--name nextcloud-db
docker.io/library/mariadb:10
# Check running containers
$ podman container ls
```
After the successful start of your new MariaDB container, you can deploy Nextcloud itself. (Note that you should replace DB_USER_PASSWORD with the password you used in the previous step. Replace NC_ADMIN and NC_PASSWORD with the username and password you want to use for the Nextcloud administrator account.)
```
# Deploy Nextcloud
$ podman run --detach
--env MYSQL_HOST=nextcloud-db.dns.podman
--env MYSQL_DATABASE=nextcloud
--env MYSQL_USER=nextcloud
--env MYSQL_PASSWORD=DB_USER_PASSWORD
--env NEXTCLOUD_ADMIN_USER=NC_ADMIN
--env NEXTCLOUD_ADMIN_PASSWORD=NC_PASSWORD
--volume nextcloud-app:/var/www/html
--volume nextcloud-data:/var/www/html/data
--network nextcloud-net
--restart on-failure
--name nextcloud
--publish 8080:80
docker.io/library/nextcloud:20
# Check running containers
$ podman container ls
```
Now that the two containers are running, you can configure your containers. Open your browser and point to “localhost:8080” (or another host name or IP address if it is running on a different server).
The first load may take some time (30 seconds) or even report “unable to load”. This is coming from Nextcloud, which is preparing the first run. In that case, wait a minute or two. Nextcloud will prompt for a username and password.
![][6]
Enter the user name and password you used previously.
![][7]
Now you are ready to go and experience Nextcloud for testing, development ,or your home server.
### Update
If you want to update one of the containers, you need to pull the new image and re-create the containers.
```
# Update mariadb
$ podman pull mariadb:10
$ podman stop nextcloud-db
$ podman rm nextcloud-db
$ podman run --detach
--env MYSQL_DATABASE=nextcloud
--env MYSQL_USER=nextcloud
--env MYSQL_PASSWORD=DB_USER_PASSWORD
--env MYSQL_ROOT_PASSWORD=DB_ROOT_PASSWORD
--volume nextcloud-db:/var/lib/mysql
--network nextcloud-net
--restart on-failure
--name nextcloud-db
docker.io/library/mariadb:10
```
Updating the Nextcloud container works exactly the same.
```
# Update Nextcloud
$ podman pull nextcloud:20
$ podman stop nextcloud
$ podman rm nextcloud
$ podman run --detach
--env MYSQL_HOST=nextcloud-db.dns.podman
--env MYSQL_DATABASE=nextcloud
--env MYSQL_USER=nextcloud
--env MYSQL_PASSWORD=DB_USER_PASSWORD
--env NEXTCLOUD_ADMIN_USER=NC_ADMIN
--env NEXTCLOUD_ADMIN_PASSWORD=NC_PASSWORD
--volume nextcloud-app:/var/www/html
--volume nextcloud-data:/var/www/html/data
--network nextcloud-net
--restart on-failure
--name nextcloud
--publish 8080:80
docker.io/library/nextcloud:20
```
Thats it; your Nextcloud installation is up-to-date again.
### Conclusion
Deploying Nextcloud with Podman is quite easy. After just a couple of minutes, you will have a very handy collaboration software, offering filesync, calendar, contacts, and much more. Check out [apps.nextcloud.com][8], which will extend the features even further.
--------------------------------------------------------------------------------
via: https://fedoramagazine.org/nextcloud-20-on-fedora-linux-with-podman/
作者:[dschier][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://fedoramagazine.org/author/danielwtd/
[b]: https://github.com/lujun9972
[1]: https://fedoramagazine.org/wp-content/uploads/2021/02/nextcloud-podman-816x345.jpg
[2]: https://fedoramagazine.org/build-your-own-cloud-with-fedora-31-and-nextcloud-server/
[3]: https://nextcloud.com/
[4]: https://en.wikipedia.org/wiki/Network_segmentation
[5]: https://fedoramagazine.org/wp-content/uploads/2021/01/nextcloud-podman-arch.png
[6]: https://fedoramagazine.org/wp-content/uploads/2021/02/Screenshot-from-2021-02-12-08-38-37-1024x211.png
[7]: https://fedoramagazine.org/wp-content/uploads/2021/02/Screenshot-from-2021-02-12-08-38-28-1024x377.png
[8]: https://apps.nextcloud.com

View File

@@ -1,160 +0,0 @@
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (Protect your Home Assistant with these backups)
[#]: via: (https://opensource.com/article/21/2/home-assistant-backups)
[#]: author: (Steve Ovens https://opensource.com/users/stratusss)
Protect your Home Assistant with these backups
======
Make sure you can recover quickly from a home automation failure with a
solid backup and hardware plan in the seventh article in this series.
![A rack of servers, blue background][1]
In the last two articles in this series on home automation with Home Assistant (HA), I walked through setting up a few [integrations][2] with a Zigbee Bridge and some [custom ESP8266][3] devices that I use for automation. The first four articles in the series discussed [what Home Assistant is][4], why you may want [local control][5], some of the [communication protocols][6] for smart home components, and how to [install Home Assistant][7] in a virtual machine (VM) using libvirt.
Now that you have a basic home automation setup, it is a good time to take a baseline of your system. In this seventh article, I will talk about snapshots, backups, and backup strategies. Let's get right into it.
### Backups vs. copies
I'll start by clearing up some ambiguity: A copy of something is not the same as a backup. Here is a brief overview of the difference between a copy and a backup. Bear in mind that this comes from the lens of an IT professional. I work with client data day in and day out. I have seen many ways that backups can go sideways, so the following descriptions may be overkill for home use. You'll have to decide just how important your Home Assistant data really is.
* **Copies:** A copy is just what it sounds. It is when you highlight something on your computer and hit **Ctrl**+**C** and paste it somewhere else with **Ctrl**+**V**. Many people may view this as backing up the source, and to some extent, that is true. However, a copy is merely a representation of a point in time. If it's taken incorrectly, the newly created file can be corrupt, leading to a false sense of security. In addition, the source may have a problem—meaning the copy will also have a problem. If you have just a single copy of a file, it's often the same as having nothing at all. When it comes to backup, the saying "one is none" is absolutely true. If you do not have files going back over time, you won't have a good idea of whether the system creating the backups has a problem.
* **Backups and snapshots:** In Home Assistant, it is a bit tricky to differentiate between a copy and a backup. First, Home Assistant uses the term "snapshot" to refer to what we traditionally think of backups. In this context, a backup is very similar to a copy because you don't use any type of backup software, at least not in the traditional sense. Normally, backup software is designed specifically to get all the files that are hidden or otherwise protected. For example, backup software for a computer (such as CloneZilla) makes an exact replica (in some cases) of the hard drive to ensure no files are missed. Home Assistant knows how to create snapshots and does it for you. You just need to worry about storing the files somewhere.
### Set a good backup strategy
Before I get into how to deal with snapshots in Home Assistant, I want to share a brief story from a recent client. Remember when I mentioned that simply having a single copy of your files doesn't give you any indication that a problem has occurred? My client was doing all of the right things when it came to backups. The team was using the proper methodology for backups, kept multiple files going back a certain period of time, ensured there were more than two copies of each backup, and was especially careful that backups were not being stored locally on the machine being backed up. Sounds great, doesn't it? They were doing everything right. Well, almost. The one thing they neglected was testing the backups. Most people put this off or disregard it entirely. I admit I am guilty of not testing my backups frequently. I do it when I remember, which is usually once every few months or so.
In my client's case, a software upgrade created a new requirement from the backup program. This was missed. The backups continued to hum along, and the automated checks passed. There were files after every backup run, they were larger than a certain amount, and the [magic file checks][8] reported the correct file type. The problem was that the file sizes shrunk significantly due to the software change. This meant the client was not backing up the data it thought.
This story has a happy ending, which brings me to my point: Because the client was doing everything else right, we could go through the backups and identify the precise moment when something changed. From this, we linked this to the date of an upgrade some weeks back. Fortunately, there was no emergency that precipitated the investigation. I happened to be doing a standard audit when I discovered the discrepancy.
The moral of the story? Without proper backup strategies, we would have had a much harder time tracking down this problem. Also, in the event of a failure, we would have had no recovery point.
A good backup strategy usually entails daily, weekly, and monthly backups. For example, you may decide to keep all your daily backups for two weeks, four weekly backups, and perhaps four monthly backups. This, in my opinion, is overkill for Home Assistant after you have a stable setup. You'll have to choose the level of precision you need. I take a backup before I make any change to the system. This gives me a known-good situation to revert to.
### Create snapshots
Great, so how do you create a snapshot in Home Assistant? The **Snapshots** menu resides inside the **Supervisor** tab on the left-size panel.
![Home Assistant snapshots][9]
(Steve Ovens, [CC BY-SA 4.0][10])
You have two options for creating a snapshot: _Full snapshot_ or _Partial snapshot_. A Full snapshot is self-explanatory. You have some options with a Partial snapshot.
![Home Assistant partial snapshots][11]
(Steve Ovens, [CC BY-SA 4.0][10])
Any component you install in Home Assistant will populate in this menu. Choose a name for your backup and click **Create**. This will take some time, depending on the speed of the disk and the size of the backup. I recommend keeping at least four backups on your machine if you can afford the space.
![Home Assistant snapshots][12]
(Steve Ovens, [CC BY-SA 4.0][10])
You can retrieve these files from Home Assistant with File Browser if you set up the **Samba share** extension.
![Samba share][13]
(Steve Ovens, [CC BY-SA 4.0][10])
Save these files somewhere safe. The name you give the backup is contained in the metadata inside Home Assistant, and the file names are randomly generated. After I copy them to a different location, I usually rename them because when I test the restoration process on a different machine, the new file name does not matter.
### My homelab strategy
I run my Home Assistant instance on top of KVM on a Linux host. I have had a few requests to go into a little more detail on this, so feel free to skip past this section as it's not directly related to HA.
Due to the nature of my job, I have a fairly large variety of hardware, which I use for a [homelab][14]. Sometimes this is because physical hosts are easier to work with than VMs for certain clustering software. Other times, this is because I keep workloads isolated to specific hardware. Either way, this means I already have a certain amount of knowledge built up around managing and dealing with KVM. Not to mention the fact that I run _almost exclusively_ open source software (with a few exceptions). Here is a basic layout of my homelab:
![KVM homelab architecture][15]
(Steve Ovens, [CC BY-SA 4.0][10])
The network-attached storage (NAS) has dual 10GB network cards that feed into uplink ports. Two of the KVM hosts have 10GB network interface cards (NICs), while the hosts on the right have regular 1GB network cards.
For Home Assistant, this is well into overkill territory. However, this infrastructure was not designed for HA. HA runs just fine on a Raspberry Pi 4 (4GB version) at my parents' house.
The VM that hosts Home Assistant has three vCPU cores of a Broadwell Core I5 CPU (circa 2015) with 8GB of RAM. The CPU tends to remain around 25% usage, and I rarely use more than 2.2GB of RAM. This is with 11 add-ons, including InfluxDB and Grafana, which are heavier applications.
While I do have shared storage, I do not use it for live migration or anything similar. Instead, I use this for backend storage for specific mount points in a VM. For example, I store the `data` directory from Nextcloud on the NAS, divorcing the data from the service.
At any rate, I have a few approaches to backups with this setup. Naturally, I use the Home Assistant snapshotting function to provide the first layer of protection. I tend to store only four weeks' worth of data on the VM. What do I do with the files themselves? Here is a diagram of how I try to keep my backups safe:
![Home Assistant backup architecture][16]
(Steve Ovens, [CC BY-SA 4.0][10])
Using the Samba add-on, I pull a copy of the snapshot onto my GNOME desktop. I configure Nextcloud using GNOME's **Online Accounts** settings.
![GNOME Online Accounts settings][17]
(Steve Ovens, [CC BY-SA 4.0][10])
Nextcloud takes a copy and puts it on my NAS. Both my desktop and the NAS use [SpiderOak One Backup][18] clients to ensure the backups are linked to more than one host. In the unlikely event that I delete a device from my SpiderOak account, the file is still linked to another device. I chose SpiderOak because it supports a Linux client, and it is privacy-focused and has no insight into what files it stores. The files are encrypted before being uploaded, and only the owner has the ability to decrypt them. The downside is that if you lose or forget your password, you lose your backups.
Finally, I keep a cold copy on an external hard drive. I have a 14TB external drive that remains off and disconnected from the NAS except when backups are running. It's not on the diagram, but I also occasionally replicate to a computer at my in-laws' house.
I can also take snapshots of the VM during critical operations (such as Home Assistant's recent upgrade from using a numbered point release to a month-based numbering system).
I use a similar pipeline for most things that I back up, although I recognize it is a bit overkill. Also, this whole process has the flaw that it relies on me. Aside from SpiderOak and Nextcloud, I have not automated this process. I have scripts that I run, but I do not run them in a cron or anything like that. In hindsight, perhaps I should work on that.
This setup may be considered extreme, but the built-in versioning in Nextcloud and SpiderOak, along with making copies in multiple locations, means that I am unlikely to suffer a failure that I can't recover from. At the very least, I should be able to dig up a close reference.
As a final precaution, I make sure to keep the important information about _how_ I set things up on my private wiki on [Wiki.js][19]. I keep a section just for home automation.
![Home automation overview][20]
(Steve Ovens, [CC BY-SA 4.0][10])
When you get into creating Node-RED automations (in the next article), I suggest you keep your own notes. I take a screenshot of the flow, write a brief description, so I know what I was attempting to achieve, and dump the flow to JSON (for brevity, I omitted the JSON from this screenshot):
![Node-RED routine][21]
(Steve Ovens, [CC BY-SA 4.0][10])
### Wrapping up
Backups are essential when you're using Home Assistant, as it is a critical component of your infrastructure that always needs to be functioning. Small downtime is acceptable, but the ability to recover from a failure quickly is crucial. Granted, I have found Home Assistant to be rock solid. It has never failed on its own; any problems I have had were external to HA. Still, if you are going to make HA a central part of your house, I strongly recommend putting a good backup strategy in place.
In the next article, I'll take a look at setting up some simple automations with Node-RED. As always, leave a comment below if you have questions, ideas, or suggestions for topics you'd like to see covered.
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/2/home-assistant-backups
作者:[Steve Ovens][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/stratusss
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/rack_server_sysadmin_cloud_520.png?itok=fGmwhf8I (A rack of servers, blue background)
[2]: https://opensource.com/article/21/1/home-automation-5-homeassistant-addons
[3]: https://opensource.com/article/21/1/home-assistant-6-custom-sensors
[4]: https://opensource.com/article/20/11/home-assistant
[5]: https://opensource.com/article/20/11/cloud-vs-local-home-automation
[6]: https://opensource.com/article/20/11/home-automation-part-3
[7]: https://opensource.com/article/20/12/home-assistant
[8]: https://linux.die.net/man/5/magic
[9]: https://opensource.com/sites/default/files/uploads/ha-setup33-snapshot1_0.png (Home Assistant snapshots)
[10]: https://creativecommons.org/licenses/by-sa/4.0/
[11]: https://opensource.com/sites/default/files/uploads/ha-setup34-snapshot2.png (Home Assistant partial snapshots)
[12]: https://opensource.com/sites/default/files/uploads/ha-setup35-snapshot3.png (Home Assistant snapshots)
[13]: https://opensource.com/sites/default/files/uploads/ha-setup36-backup-samba.png (Samba share)
[14]: https://opensource.com/article/19/3/home-lab
[15]: https://opensource.com/sites/default/files/uploads/kvm_lab.png (KVM homelab architecture)
[16]: https://opensource.com/sites/default/files/uploads/home_assistant_backups.png (Home Assistant backup architecture)
[17]: https://opensource.com/sites/default/files/uploads/gnome-online-account.png (GNOME Online Accounts settings)
[18]: https://spideroak.com/
[19]: https://wiki.js.org/
[20]: https://opensource.com/sites/default/files/uploads/confluence_home_automation_overview.png (Home automation overview)
[21]: https://opensource.com/sites/default/files/uploads/node_red_bedtime.png (Node-RED routine)

View File

@@ -1,224 +0,0 @@
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (Review of Five popular Hyperledger DLTs- Fabric, Besu, Sawtooth, Iroha and Indy)
[#]: via: (https://www.linux.com/news/review-of-five-popular-hyperledger-dlts-fabric-besu-sawtooth-iroha-and-indy/)
[#]: author: (Dan Brown https://training.linuxfoundation.org/announcements/review-of-five-popular-hyperledger-dlts-fabric-besu-sawtooth-iroha-and-indy/)
Review of Five popular Hyperledger DLTs- Fabric, Besu, Sawtooth, Iroha and Indy
======
_by Matt Zand_
As companies are catching up in adopting blockchain technology, the choice of a private blockchain platform becomes very vital. Hyperledger, whose open source projects support/power more [enterprise blockchain use cases][1] than others, is currently leading the race of private Distributed Ledger Technology (DLT) implementation. Working from the assumption that you know how blockchain works and what is the design philosophy behind [Hyperledgers ecosystem][2], in this article we will briefly review five active Hyperledger DLTs. In addition to DLTs discussed in this article, Hyperledger ecosystem has more supporting tools and libraries that I will cover in more detail in my future articles.
This article mainly targets those who are relatively new to Hyperledger. This article would be a great resource for those interested in providing blockchain solution architect services and doing blockchain enterprise consulting and development. The materials included in this article will help you understand Hyperledger DLTs as a whole and use its high-level overview as a guideline for making the best of each Hyperledger project.
Since Hyperledger is supported by a robust open source community, new projects are being added to the Hyperledger ecosystem regularly. At the time of this writing, Feb 2021, it consists of six active projects and 10 others which are at the incubation stage. Each project has unique features and advantages.
**1- Hyperledger Fabric**
[Hyperledger Fabric][3] is the most popular Hyperledger framework. Smart contracts (also known as **chaincode**) are written in [Golang][4] or JavaScript, and run in Docker containers. Fabric is known for its extensibility and allows enterprises to build distributed ledger networks on top of an established and successful architecture. A permissioned blockchain, initially contributed by IBM and Digital Asset,  Fabric is designed to be a foundation for developing applications or solutions with a modular architecture. It takes plugin components for providing functionalities such as consensus and membership services. Like Ethereum, Hyperledger Fabric can host and execute smart contracts, which are named chaincode. A Fabric network consists of peer nodes, which execute smart contracts (chaincode), query ledger data, validate transactions, and interact with applications. User-entered transactions are channeled to an ordering service component, which initially serves to be a consensus mechanism for Hyperledger Fabric. Special nodes called Orderer nodes validate the transactions, ensure the consistency of the blockchain, and send the validated transactions to the peers of the network as well as to membership service provider (MSP) services.
Two major highlights of Hyperledger Fabric versus Ethereum are:
* **Multi-ledger**: Each node on Ethereum has a replica of a single ledger in the network. However, Fabric nodes can carry multiple ledgers on each node, which is a great feature for enterprise applications.
* **Private Data**: In addition to a private channel feature, unlike with Ethereum, Fabric members within a consortium can exchange private data among themselves without disseminating them through Fabric channel, which is very useful for enterprise applications.
[Here][5] is a good article for reviewing all Hyperledger Fabric components like peer, channel and, chaincode that are essential for building blockchain applications. In short, thorough understanding of all Hyperledger Fabric components is highly recommended for building, deploying and managing enterprise-level Hyperledger Fabric applications.
**2- Hyperledger Besu**
Hyperledger Besu is an open source Ethereum client developed under the Apache 2.0 license and written in Java. It can be run on the Ethereum public network or on private permissioned networks, as well as test networks such as Rinkeby, Ropsten, and Gorli. Hyperledger Besu supports several consensus algorithms including PoW, PoA, and IBFT, and has comprehensive permissioning schemes designed specifically for uses in a consortium environment.
Hyperledger Besu implements the Enterprise Ethereum Alliance (EEA) specification. The EEA specification was established to create common interfaces amongst the various open and closed source projects within Ethereum, to ensure users do not have vendor lock-in, and to create standard interfaces for teams building applications. Besu implements enterprise features in alignment with the EEA client specification.
As a basic Ethereum Client, Besu has the following features:
* It connects to the blockchain network to synchronize blockchain transaction data or emit events to the network.
* It processes transactions through smart contracts in an Ethereum Virtual Machine (EVM) environment.
* It uses a data storage of networks (blocks).
* It publishes client API interfaces for developers to interact with the blockchain network.
Besu implements [Proof of Work][6] and [Proof of Authority][7] (PoA) consensus mechanisms. Further, Hyperledger Besu implements several PoA protocols, including Clique and IBFT 2.0.
Clique is a proof-of-authority blockchain consensus protocol. The blockchain runs Clique protocol maintaining the list of authorized signers. These approved signers directly mine and seal all blocks without mining. Therefore, the transaction task is computationally light. When creating a block, a miner collects and executes transactions, updates the network state with the calculated hash of the block and signs the block using his private key. By using a defined period of time to create a block, Clique can limit the number of processed transactions.
IBFT 2.0 (Istanbul BFT 2.0) is a PoA **Byzantine-Fault-Tolerant** (**BFT**) blockchain consensus protocol. Transactions and blocks in the network are validated by authorized accounts, known as validators. Validators collect, validate and execute transactions and create the next block. Existing validators can propose and vote to add or remove validators and maintain a dynamic validator set. The consensus can ensure immediate finality. As the name suggests, IBFT 2.0 builds upon the IBFT blockchain consensus protocol with improved safety and liveness. In IBFT 2.0 blockchain, all valid blocks are directly added in the main chain and there are no forks.
**3- Hyperledger Sawtooth**
Sawtooth is the second Hyperledger project to reach 1.0 release maturity. Sawtooth-core is written in Python, while Sawtooth Raft and Sawtooth Sabre are written in Rust. It also has JavaScript and Golang components. Sawtooth supports both permissioned and permissionless deployments. It supports the EVM through a collaboration with the Hyperledger Burrow. By design, Hyperledger Sawtooth is created to address issues of performance. As such, one of its distinct features compared to other Hyperledger DLTs is that each node in Sawtooth can act as an orderer by validating and approving a transaction. Other notable features are:
* **Parallel Transaction Execution**: While many blockchains use serial transaction execution to ensure consistent ordering at every node on the network, Sawtooth follows an advanced parallel scheduler that classifies transactions into parallel flows that eventually leads to the boost in transaction processing performance.
* **Separation of Application from Core**: Sawtooth simplifies the development and deployment of an application by separating the application level from the core system level. It offers smart contract abstraction to allow developers to create contract logic in the programming language of their choice.
* **Custom Transaction Processors**: In Sawtooth, each application can define the custom transaction processors to meet its unique requirements. It provides transaction families to serve as an approach for low-level functions, like storing on-chain permissions, managing chain-wide settings and for particular applications such as saving block information and performance analysis.
**4- Hyperledger Iroha**
Hyperledger Iroha is designed to target the creation and management of complex digital assets and identities. It is written in C++ and is user friendly. Iroha has a powerful role-based model for access control and supports complex analytics. While using Iroha for identity management, querying and performing commands are only limited to the participants who have access to the Iroha network. A robust permissions system ensures that all transactions are secure and controlled. Some of its highlights are:
* **Ease of use:** You can easily create and manage simple, as well as complex, digital assets (e.g., cryptocurrency or personal medical data).
* **Built-in Smart Contracts:** You can easily integrate blockchain into a business process using built-in smart-contracts called “commands.” As such, developers need not to write complicated smart-contracts because they are available in the form of commands.
* **BFT:** Iroha uses BFT consensus algorithm which makes it suitable for businesses that require verifiable data consistency at a low cost.
**5- Hyperledger Indy**
As a self-sovereign identity management platform, Hyperledger Indy is built explicitly for decentralized identity management. The server portion, Indy node, is built in Python, while the Indy SDK is written in Rust. It offers tools and reusable components to manage digital identities on blockchains or other distributed ledgers. Hyperledger Indy architecture is well-suited for every application that requires heavy work on identity management since Indy is easily interpretable across multiple domains, organization silos and applications. As such, identities are securely stored and shared with all parties involved. Some notable highlights of Hyperledger Indy are:
●        Identity Correlation-resistant: According to the Hyperledger Indy documentation, Indy is completely identity correlation-resistant. So, you do not need to worry about connecting or mixing one Id with another. That means, you can not connect two Ids or find two similar Ids in the ledger.
●        Decentralized Identifiers (DIDs): According to the Hyperledger Indy documentation, all the decentralized identifiers are globally resolvable and unique without needing any central party in the mix. That means, every decentralized identity on the Indy platform will have a unique identifier that will solely belong to you. As a result, no one can claim or even use your identity on your behalf. So, it would eliminate the chances of identity theft.
●        Zero-Knowledge Proofs: With help from Zero-Knowledge Proof, you can disclose only the information necessary without anything else. So, when you have to prove your credentials, you can only choose to release the information that you need depending on the party that is requesting it. For instance, you may choose to share your data of birth only with one party whereas to release your driver license and financial docs to another. In short, Indy gives users great flexibility in sharing their private data whenever and wherever needed.
**Summary**
In this article, we briefly reviewed five popular Hyperledger DLTs. We started off by going over Hyperledger Fabric and its main components and some of its highlights compared to public blockchain platforms like Ethereum. Even though Fabric is currently used heavily for supply chain management, if you are doing lots of specific works in supply chain domain, you should explore Hyperledger Grid too. Then, we moved on to learning how to use Hyperledger Besu for building public consortium blockchain applications that support multiple consensus algorithms and how to manage Besu from EVM. Next, we covered some highlights of Hyperledger Sawtooth such as how it is designed for high performance. For instance, we learned how a single node in Sawtooth can act as an orderer by approving and validating transactions in the network. The last two DLTs (Hyperledger Iroha and Indy) are specifically geared toward digital asset management and identity . So if you are working on a project that heavily uses identity management, you should explore and use either Iroha or Indy instead of Fabric.
I have included reference and resource links for those interested in exploring topics discussed in this article in depth.
For more references on all Hyperledger projects, libraries and tools, visit the below documentation links:
1. [Hyperledger Indy Project][8]
2. [Hyperledger Fabric Project][9]
3. [Hyperledger Aries Library][10]
4. [Hyperledger Iroha Project][11]
5. [Hyperledger Sawtooth Project][12]
6. [Hyperledger Besu Project][13]
7. [Hyperledger Quilt Library][14]
8. [Hyperledger Ursa Library][15]
9. [Hyperledger Transact Library][16]
10. [Hyperledger Cactus Project][17]
11. [Hyperledger Caliper Tool][18]
12. [Hyperledger Cello Tool][19]
13. [Hyperledger Explorer Tool][20]
14. [Hyperledger Grid (Domain Specific)][21]
15. [Hyperledger Burrow Project][22]
16. [Hyperledger Avalon Tool][23]
**Resources**
* Free Training Courses from The Linux Foundation &amp; Hyperledger
* [Blockchain: Understanding Its Uses and Implications (LFS170)][24]
* [Introduction to Hyperledger Blockchain Technologies (LFS171)][25]
* [Introduction to Hyperledger Sovereign Identity Blockchain Solutions: Indy, Aries &amp; Ursa (LFS172)][26]
* [Becoming a Hyperledger Aries Developer (LFS173)][27]
* [Hyperledger Sawtooth for Application Developers (LFS174)][28]
* eLearning Courses from The Linux Foundation &amp; Hyperledger
* [Hyperledger Fabric Administration (LFS272)][29]
* [Hyperledger Fabric for Developers (LFD272)][30]
* Certification Exams from The Linux Foundation &amp; Hyperledger
* [Certified Hyperledger Fabric Administrator (CHFA)][31]
* [Certified Hyperledger Fabric Developer (CHFD)][32]
* [Hands-On Smart Contract Development with Hyperledger Fabric V2][33] Book by Matt Zand and others.
* [Essential Hyperledger Sawtooth Features for Enterprise Blockchain Developers][34]
* [Blockchain Developer Guide- How to Install Hyperledger Fabric on AWS][35]
* [Blockchain Developer Guide- How to Install and work with Hyperledger Sawtooth][36]
* [Intro to Blockchain Cybersecurity (Coding Bootcamps)][37]
* [Intro to Hyperledger Sawtooth for System Admins (Coding Bootcamps)][38]
* [Blockchain Developer Guide- How to Install Hyperledger Iroha on AWS][39]
* [Blockchain Developer Guide- How to Install Hyperledger Indy and Indy CLI on AWS][40]
* [Blockchain Developer Guide- How to Configure Hyperledger Sawtooth Validator and REST API on AWS][41]
* [Intro blockchain development with Hyperledger Fabric (Coding Bootcamps)][42]
* [How to build DApps with Hyperledger Fabric][43]
* [Blockchain Developer Guide- How to Build Transaction Processor as a Service and Python Egg for Hyperledger Sawtooth][44]
* [Blockchain Developer Guide- How to Create Cryptocurrency Using Hyperledger Iroha CLI][45]
* [Blockchain Developer Guide- How to Explore Hyperledger Indy Command Line Interface][46]
* [Blockchain Developer Guide- Comprehensive Blockchain Hyperledger Developer Guide from Beginner to Advance Level][47]
* [Blockchain Management in Hyperledger for System Admins][48]
* [Hyperledger Fabric for Developers (Coding Bootcamps)][49]
* [Free White Papers from Hyperledger][50]
* [Free Webinars from Hyperledger][51]
* [Hyperledger Wiki][52]
**About the Author**
**Matt Zand** is a serial entrepreneur and the founder of 3 tech startups: [DC Web Makers][53], [Coding Bootcamps][54] and [High School Technology Services][55]. He is a leading author of [Hands-on Smart Contract Development with Hyperledger Fabric][33] book by OReilly Media. He has written more than 100 technical articles and tutorials on blockchain development for Hyperledger, Ethereum and Corda R3 platforms. At DC Web Makers, he leads a team of blockchain experts for consulting and deploying enterprise decentralized applications. As chief architect, he has designed and developed blockchain courses and training programs for Coding Bootcamps. He has a masters degree in business management from the University of Maryland. Prior to blockchain development and consulting, he worked as senior web and mobile App developer and consultant, angel investor, business advisor for a few startup companies. You can connect with him on LI: <https://www.linkedin.com/in/matt-zand-64047871>
The post [Review of Five popular Hyperledger DLTs- Fabric, Besu, Sawtooth, Iroha and Indy][56] appeared first on [Linux Foundation Training][57].
--------------------------------------------------------------------------------
via: https://www.linux.com/news/review-of-five-popular-hyperledger-dlts-fabric-besu-sawtooth-iroha-and-indy/
作者:[Dan Brown][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://training.linuxfoundation.org/announcements/review-of-five-popular-hyperledger-dlts-fabric-besu-sawtooth-iroha-and-indy/
[b]: https://github.com/lujun9972
[1]: https://blockchain.dcwebmakers.com/blog/comprehensive-overview-and-analysis-of-blockchain-use-cases-in-many-industries.html
[2]: https://weg2g.com/application/touchstonewords/article-intro-to-hyperledger-family-and-hyperledger-blockchain-ecosystem.php
[3]: https://learn.coding-bootcamps.com/blog/202224/why-build-blockchain-applications-with-hyperledger-fabric
[4]: https://learn.coding-bootcamps.com/p/learn-go-programming-language-by-examples
[5]: https://coding-bootcamps.com/blog/review-of-hyperledger-fabric-architecture-and-components.html
[6]: https://coding-bootcamps.com/blog/how-proof-of-work-consensus-works-in-blockchain.html
[7]: https://coding-bootcamps.com/blog/how-proof-of-stake-consensus-works-in-blockchain.html
[8]: https://www.hyperledger.org/use/hyperledger-indy
[9]: https://www.hyperledger.org/use/fabric
[10]: https://www.hyperledger.org/projects/aries
[11]: https://www.hyperledger.org/projects/iroha
[12]: https://www.hyperledger.org/projects/sawtooth
[13]: https://www.hyperledger.org/projects/besu
[14]: https://www.hyperledger.org/projects/quilt
[15]: https://www.hyperledger.org/projects/ursa
[16]: https://www.hyperledger.org/projects/transact
[17]: https://www.hyperledger.org/projects/cactus
[18]: https://www.hyperledger.org/projects/caliper
[19]: https://www.hyperledger.org/projects/cello
[20]: https://www.hyperledger.org/projects/explorer
[21]: https://www.hyperledger.org/projects/grid
[22]: https://www.hyperledger.org/projects/hyperledger-burrow
[23]: https://www.hyperledger.org/projects/avalon
[24]: https://training.linuxfoundation.org/training/blockchain-understanding-its-uses-and-implications/
[25]: https://training.linuxfoundation.org/training/blockchain-for-business-an-introduction-to-hyperledger-technologies/
[26]: https://training.linuxfoundation.org/training/introduction-to-hyperledger-sovereign-identity-blockchain-solutions-indy-aries-and-ursa/
[27]: https://training.linuxfoundation.org/training/becoming-a-hyperledger-aries-developer-lfs173/
[28]: https://training.linuxfoundation.org/training/hyperledger-sawtooth-application-developers-lfs174/
[29]: https://training.linuxfoundation.org/training/hyperledger-fabric-administration-lfs272/
[30]: https://training.linuxfoundation.org/training/hyperledger-fabric-for-developers-lfd272/
[31]: https://training.linuxfoundation.org/certification/certified-hyperledger-fabric-administrator-chfa/
[32]: https://training.linuxfoundation.org/certification/certified-hyperledger-fabric-developer/
[33]: https://www.oreilly.com/library/view/hands-on-smart-contract/9781492086116/
[34]: https://weg2g.com/application/touchstonewords/article-essential-hyperledger-sawtooth-features-for-enterprise-blockchain-developers.php
[35]: https://myhsts.org/tutorial-learn-how-to-install-blockchain-hyperledger-fabric-on-amazon-web-services.php
[36]: https://myhsts.org/tutorial-learn-how-to-install-and-work-with-blockchain-hyperledger-sawtooth.php
[37]: https://learn.coding-bootcamps.com/p/learn-how-to-secure-blockchain-applications-by-examples
[38]: https://learn.coding-bootcamps.com/p/introduction-to-hyperledger-sawtooth-for-system-admins
[39]: https://myhsts.org/tutorial-learn-how-to-install-blockchain-hyperledger-iroha-on-amazon-web-services.php
[40]: https://myhsts.org/tutorial-learn-how-to-install-blockchain-hyperledger-indy-on-amazon-web-services.php
[41]: https://myhsts.org/tutorial-learn-how-to-configure-hyperledger-sawtooth-validator-and-rest-api-on-aws.php
[42]: https://learn.coding-bootcamps.com/p/live-and-self-paced-blockchain-development-with-hyperledger-fabric
[43]: https://learn.coding-bootcamps.com/p/live-crash-course-for-building-dapps-with-hyperledger-fabric
[44]: https://myhsts.org/tutorial-learn-how-to-build-transaction-processor-as-a-service-and-python-egg-for-hyperledger-sawtooth.php
[45]: https://myhsts.org/tutorial-learn-how-to-work-with-hyperledger-iroha-cli-to-create-cryptocurrency.php
[46]: https://myhsts.org/tutorial-learn-how-to-work-with-hyperledger-indy-command-line-interface.php
[47]: https://myhsts.org/tutorial-comprehensive-blockchain-hyperledger-developer-guide-for-all-professional-programmers.php
[48]: https://learn.coding-bootcamps.com/p/learn-blockchain-development-with-hyperledger-by-examples
[49]: https://learn.coding-bootcamps.com/p/hyperledger-blockchain-development-for-developers
[50]: https://www.hyperledger.org/learn/white-papers
[51]: https://www.hyperledger.org/learn/webinars
[52]: https://wiki.hyperledger.org/
[53]: https://blockchain.dcwebmakers.com/
[54]: http://coding-bootcamps.com/
[55]: https://myhsts.org/
[56]: https://training.linuxfoundation.org/announcements/review-of-five-popular-hyperledger-dlts-fabric-besu-sawtooth-iroha-and-indy/
[57]: https://training.linuxfoundation.org/

View File

@@ -1,182 +0,0 @@
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (What is PPA Purge? How to Use it in Ubuntu and other Debian-based Distributions?)
[#]: via: (https://itsfoss.com/ppa-purge/)
[#]: author: (Abhishek Prakash https://itsfoss.com/author/abhishek/)
What is PPA Purge? How to Use it in Ubuntu and other Debian-based Distributions?
======
PPA is a popular method of installing additional applications or newer versions of a software in Ubuntu.
I have written a [detailed guide on PPA][1] so I will just quickly recall it here. PPA is a mechanism developed by Ubuntu to enable developers to provide their own repositories. When you add a PPA, you add additional repository to your system and thus you can download applications from this additional repository.
```
sudo add-apt-repository ppa:ppa-address
sudo apt update
sudo apt install package_from_ppa
```
I have also written about [deleting PPAs from your system][2]. I briefly mentioned the PPA Purge tool in that article. In this tutorial, youll get more detailed information about this handy utility.
### What is PPA Purge?
PPA Purge is a command line tool that disables a PPA repository from your software sources list. Apart from that, it reverts the system back to official Ubuntu packages. This is a different behavior than simply deleting the PPA repository.
Suppose application ABC has version x available from Ubuntu repositories. You add a PPA that provides a higher version y of the same application/package ABC. When your Linux system finds that the same package is available from multiple sources, it uses the source that provides a newer version.
In this example, youll have version y of application ABC installed thanks to the PPA you added.
Normally, you would remove the application and then remove the PPA from sources list. But if you use ppa-purge to disable the said PPA, your application ABC will automatically revert to the older version x provided by Ubuntu repositories.
Do you see the difference? Probably not. Let me explain it to you with real examples.
#### Reverting applications to the official version provided by Ubuntu
I heard that the [upcoming VLC 4.0 version has major UI overhaul][3]. I wanted to try it before it is officially released and so I used the [daily build PPA of VLC][4] to get the under-development version 4.
Take a look at the screenshot below. I have added the VLC PPA (videolan/master-daily) and this PPA provides VLC version 4.0 release candidate (RC) version. Ubuntu repositories provide VLC version 3.0.11.
![][5]
If I use the ppa-purge command with the VLC daily build PPA, it disables the PPA and reverts the installed VLC version to 3.0.11 which is available from Ubuntus universal repository.
![][6]
You can see that it informs you that some packages are going to be downgraded.
![][7]
When the daily build VLC PPA is purged, the installed version reverts to what Ubuntu provides from its official repositories.
![][8]
You might think that VLC was downgraded because it was upgraded from version 3.0.11 to VLC 4.0 with the PPA. But here is a funny thing. Even if I had used the PPA to install VLC 4.0 RC version afresh (instead of upgrading it), it would still be downgraded instead of being removed from the system.
Does it mean ppa-purge command cannot remove applications along with disabling the PPA? Not quite so. Let me show another example.
#### PPA Purge impact on application only available from a PPA
I recently stumbled across Plots, a [nifty tool for plotting mathematical graphs][9]. Since it is a new application, it is not available in Ubuntu repositories yet. I used [its PPA][10] to install it.
If I use ppa-purge command on this PPA, it disables the PPA first and then looks to revert it to the original version. But there is no original version in Ubuntus repositories. So, it proceeds to [uninstall the application from Ubuntu][11].
The entire process is depicted in the single picture below. Pointer 1 is for adding PPA, pointer 2 is for installing the application named plots. I have discarded the input for these two commands with [redirection in Linux][12].
You can see that when PPA Purge is used (pointer 3), it disables the PPA (pointer 4) and then proceeds to inform that the application plots will be removed (pointer 5).
![][13]
#### Deleting a PPA vs disabling it
I have repeatedly used the term disabling PPA with PPA Purge. There is a difference between disabling PPA and deleting it.
When you add a PPA, it adds a new file in the /etc/apt/sources.list.d directory. This file has the URL of the repository.
Disabling the PPA keeps this file but it is commented out the repository in the PPAs file. Now this repository is not considered while updating or installing software.
![][14]
You can see disabled PPA repository in Software &amp; Updates tool:
![][15]
When you delete a PPA, it means deleting the PPAs file from etc/apt/sources.list.d directory. You wont see it anywhere on the system.
![PPA deleted][16]
Why disable a PPA instead of deleting it? Because it is easier to re-enable it. You can do just check the box in Software &amp; Updates tool or edit the PPA file and remove the leading # to uncomment the repository.
#### Recap of what PPA Purge does
If it was too much information, let me summarize the main points of what the ppa-purge script/tool does:
* PPA Purge disables a given PPA but doesnt delete it.
* If there was a new application (which is not available from any sources other than only the PPA) installed with the given PPA, it is uninstalled.
* If the PPA upgraded an already installed application, that application will be reverted to the version provided by the official Ubuntu repositories.
* If you used the PPA to install (not upgrade) a newer version of an application (which is also available from the official Ubuntu repository), using PPA Purge will downgrade the application version to the one available from Ubuntu repositories.
### Using PPA Purge
Alright! Enough explanation. You might be wondering how to use PPA Purge.
You need to install ppa-purge tool first. Ensure that you have [universe repository enabled][17] already.
```
sudo apt install ppa-purge
```
As far using PPA Purge, you should provide the PPA name in a format similar to what you use for adding it:
```
sudo ppa-purge ppa:ppa-name
```
Heres a real example:
![][18]
If you are not sure of the PPA name, [use the apt show command][19] to display the source repository of the package in question.
```
apt show vlc
```
![Finding PPA source URL][20]
For example, the source for VLC PPA shows <http://ppa.launchpad.net/videolan/master-daily/ubuntu> groovy/main. Out of this the terms after ppa.launchpad.net and before Ubuntu are part of PPA name. So here, you get the PPA name as videolan/master-daily.
If you have to use to purge the PPA videolan/master-daily, you use it like this by adding `ppa:` before PPA name:
```
sudo ppa-purge ppa:videolan/master-daily
```
### Do you purge your PPAs?
I wanted to keep this article short and crisp but it seems I went in a little bit of more detail.As long as you learn something new, you wont mind the additional details, will you?
PPA Purge is a nifty utility that allows you to test newer or beta versions of applications and then easily revert to the original version provided by the distribution. If a PPA has more than one application, it works on all of them.
Of course, you can do all these stuff manually which is to disable the PPA, remove the application and install it again to get the version provided by the distribution. PPA Purge makes the job easier.
Do you use ppa-purge already or will you start using it from now onwards? Did I miss some crucial information or do you still have some doubts on this topic? Please feel free to use the comment sections.
--------------------------------------------------------------------------------
via: https://itsfoss.com/ppa-purge/
作者:[Abhishek Prakash][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/abhishek/
[b]: https://github.com/lujun9972
[1]: https://itsfoss.com/ppa-guide/
[2]: https://itsfoss.com/how-to-remove-or-delete-ppas-quick-tip/
[3]: https://news.itsfoss.com/vlc-4-features/
[4]: https://launchpad.net/~videolan/+archive/ubuntu/master-daily
[5]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/02/vlc-ppa.png?resize=800%2C400&ssl=1
[6]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/02/using-ppap-purge.png?resize=800%2C506&ssl=1
[7]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/02/downgrade-packages-with-ppa-purge.png?resize=800%2C506&ssl=1
[8]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/02/package-reverted-ppa-purge.png?resize=800%2C405&ssl=1
[9]: https://itsfoss.com/plots-graph-app/
[10]: https://launchpad.net/~apandada1/+archive/ubuntu/plots/
[11]: https://itsfoss.com/uninstall-programs-ubuntu/
[12]: https://linuxhandbook.com/redirection-linux/
[13]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/02/ppa-purge-deleting-apps.png?resize=800%2C625&ssl=1
[14]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/02/disabled-ppa.png?resize=800%2C295&ssl=1
[15]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/02/disabled-ppa-ubuntu.png?resize=800%2C398&ssl=1
[16]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/02/ppa-deleted.png?resize=800%2C271&ssl=1
[17]: https://itsfoss.com/ubuntu-repositories/
[18]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/02/ppa-purge-example-800x379.png?resize=800%2C379&ssl=1
[19]: https://itsfoss.com/apt-search-command/
[20]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/02/apt-show-find-ppa-source.png?resize=800%2C341&ssl=1

View File

@@ -1,598 +0,0 @@
[#]: subject: "A step-by-step guide to Knative eventing"
[#]: via: "https://opensource.com/article/21/2/knative-eventing"
[#]: author: "Jessica Cherry https://opensource.com/users/cherrybomb"
[#]: collector: "lkxed"
[#]: translator: " "
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
A step-by-step guide to Knative eventing
======
Knative eventing is a way to create, send, and verify events in your cloud-native environment.
![Computer laptop in space][1]
Image by: Opensource.com
In a previous article, I covered [how to create a small app with Knative][2], which is an open source project that adds components to [Kubernetes][3] for deploying, running, and managing [serverless, cloud-native][4] applications. In this article, I'll explain Knative eventing, a way to create, send, and verify events in your cloud-native environment.
Events can be generated from many sources in your environment, and they can be confusing to manage or define. Since Knative follows the [CloudEvents][5] specification, it allows you to have one common abstraction point for your environment, where the events are defined to one specification.
This article explains how to install Knative eventing version 0.20.0 and create, trigger, and verify events. Because there are many steps involved, I suggest you look at my [GitHub repo][6] to walk through this article with the files.
### Set up your configuration
This walkthrough uses [Minikube][7] with Kubernetes 1.19.0. It also makes some configuration changes to the Minikube environment.
**Minikube pre-configuration commands:**
```
$ minikube config set kubernetes-version v1.19.0
$ minikube config set memory 4000
$ minikube config set cpus 4
```
Before starting Minikube, run the following commands to make sure your configuration stays and start Minikube:
```
$ minikube delete
$ minikube start
```
### Install Knative eventing
Install the Knative eventing custom resource definitions (CRDs) using kubectl. The following shows the command and a snippet of the output:
```
$ kubectl apply --filename https://github.com/knative/eventing/releases/download/v0.20.0/eventing-crds.yaml
customresourcedefinition.apiextensions.k8s.io/apiserversources.sources.knative.dev created
customresourcedefinition.apiextensions.k8s.io/brokers.eventing.knative.dev created
customresourcedefinition.apiextensions.k8s.io/channels.messaging.knative.dev created
customresourcedefinition.apiextensions.k8s.io/triggers.eventing.knative.dev created
```
Next, install the core components using kubectl:
```
$ kubectl apply --filename https://github.com/knative/eventing/releases/download/v0.20.0/eventing-core.yaml
namespace/knative-eventing created
serviceaccount/eventing-controller created
clusterrolebinding.rbac.authorization.k8s.io/eventing-controller created
```
Since you're running a standalone version of the Knative eventing service, you must install the in-memory channel to pass events. Using kubectl, run:
```
$ kubectl apply --filename https://github.com/knative/eventing/releases/download/v0.20.0/in-memory-channel.yaml
```
Install the broker, which utilizes the channels and runs the event routing:
```
$ kubectl apply --filename https://github.com/knative/eventing/releases/download/v0.20.0/mt-channel-broker.yaml
clusterrole.rbac.authorization.k8s.io/knative-eventing-mt-channel-broker-controller created
clusterrole.rbac.authorization.k8s.io/knative-eventing-mt-broker-filter created
```
Next, create a namespace and add a small broker to it; this broker routes events to triggers. Create your namespace using kubectl:
```
$ kubectl create namespace eventing-test
namespace/eventing-test created
```
Now create a small broker named `default` in your namespace. The following is the YAML from my **broker.yaml** file (which can be found in my GitHub repository):
```
apiVersion: eventing.knative.dev/v1
kind: broker
metadata:
  name: default
  namespace: eventing-test
```
Then apply your broker file using kubectl:
```
$ kubectl create -f broker.yaml
   broker.eventing.knative.dev/default created
```
Verify that everything is up and running (you should see the confirmation output) after you run the command:
```
$ kubectl -n eventing-test get broker default                                                              
NAME      URL                                                                              AGE    READY   REASON
default   http://broker-ingress.knative-eventing.svc.cluster.local/eventing-test/default   3m6s   True
```
You'll need this URL from the broker output later for sending events, so save it.
### Create event consumers
Now that everything is installed, you can start configuring the components to work with events.
First, you need to create event consumers. You'll create two consumers in this walkthrough: **hello-display** and **goodbye-display**. Having two consumers allows you to see how to target a consumer per event message.
**The hello-display YAML code:**
```
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-display
spec:
  replicas: 1
  selector:
    matchLabels: &labels
      app: hello-display
  template:
    metadata:
      labels: *labels
    spec:
      containers:
        - name: event-display
          image: gcr.io/knative-releases/knative.dev/eventing-contrib/cmd/event_display
---
kind: Service
apiVersion: v1
metadata:
  name: hello-display
spec:
  selector:
    app: hello-display
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
```
**The goodbye-display YAML code:**
```
apiVersion: apps/v1
kind: Deployment
metadata:
  name: goodbye-display
spec:
  replicas: 1
  selector:
    matchLabels: &labels
      app: goodbye-display
  template:
    metadata:
      labels: *labels
    spec:
      containers:
        - name: event-display
          # Source code: https://github.com/knative/eventing-contrib/tree/master/cmd/event_display
          image: gcr.io/knative-releases/knative.dev/eventing-contrib/cmd/event_display
---
kind: Service
apiVersion: v1
metadata:
  name: goodbye-display
spec:
  selector:
    app: goodbye-display
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8080
```
The differences in the YAML between the two consumers are in the `app` and `metadata name` sections. While both consumers are on the same ports, you can target one when generating an event. Create the consumers using kubectl:
```
$ kubectl -n eventing-test apply -f hello-display.yaml
deployment.apps/hello-display created
service/hello-display created
$ kubectl -n eventing-test apply -f goodbye-display.yaml
deployment.apps/goodbye-display created
service/goodbye-display created
```
Check to make sure the deployments are running after you've applied the YAML files:
```
$ kubectl -n eventing-test get deployments hello-display goodbye-display
NAME              READY   UP-TO-DATE   AVAILABLE   AGE
hello-display     1/1     1            1           2m4s
goodbye-display   1/1     1            1           34s
```
### Create triggers
Now, you need to create the triggers, which define the events the consumer receives. You can define triggers to use any filter from your cloud events. The broker receives events from the trigger and sends the events to the correct consumer. This set of examples creates two triggers with different definitions. For example, you can send events with the attribute type `greeting` to the `hello-display` consumer.
**The greeting-trigger.yaml code:**
```
apiVersion: eventing.knative.dev/v1
kind: Trigger
metadata:
  name: hello-display
spec:
  broker: default
  filter:
    attributes:
      type: greeting
  subscriber:
    ref:
     apiVersion: v1
     kind: Service
     name: hello-display
```
To create the first trigger, apply your YAML file:
```
$ kubectl -n eventing-test apply -f greeting-trigger.yaml
trigger.eventing.knative.dev/hello-display created
```
Next, make the second trigger using **sendoff-trigger.yaml**. This sends anything with the attribute `source sendoff` to your `goodbye-display` consumer.
**The sendoff-trigger.yaml code:**
```
apiVersion: eventing.knative.dev/v1
kind: Trigger
metadata:
  name: goodbye-display
spec:
  broker: default
  filter:
    attributes:
      source: sendoff
  subscriber:
    ref:
      apiVersion: v1
      kind: Service
      name: goodbye-display
```
Next, apply your second trigger definition to the cluster:
```
$ kubectl -n eventing-test apply -f sendoff-trigger.yaml
trigger.eventing.knative.dev/goodbye-display created
```
Confirm everything is correctly in place by getting your triggers from the cluster using kubectl:
```
$ kubectl -n eventing-test get triggers
NAME              BROKER    SUBSCRIBER_URI                                            AGE   READY  
goodbye-display   default   http://goodbye-display.eventing-test.svc.cluster.local/   24s   True    
hello-display     default   http://hello-display.eventing-test.svc.cluster.local/     46s   True
```
### Create an event producer
Create a pod you can use to send events. This is a simple pod deployment with curl and SSH access for you to [send events using curl][8]. Because the broker can be accessed only from inside the cluster where Knative eventing is installed, the pod needs to be in the cluster; this is the only way to send events into the cluster. Use the **event-producer.yaml** file with this code:
```
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: curl
  name: curl
spec:
  containers:
    - image: radial/busyboxplus:curl
      imagePullPolicy: IfNotPresent
      name: curl
      resources: {}
      stdin: true
      terminationMessagePath: /dev/termination-log
      terminationMessagePolicy: File
      tty: true
```
Next, deploy the pod by using kubectl:
```
$ kubectl -n eventing-test apply -f event-producer.yaml
pod/curl created
```
To verify, get the deployment and make sure the pod is up and running:
```
$ kubectl get pods -n eventing-test
NAME                               READY   STATUS    RESTARTS   AGE
curl                               1/1     Running   0          8m13s
```
### Send some events
Since this article has been so configuration-heavy, I imagine you'll be happy to finally be able to send some events and test out your services. Events have to be passed internally in the cluster. Usually, events would be defined around applications internal to the cluster and come from those applications. But this example will manually send events from your pod named **curl**.
Begin by logging into the pod:
```
$ kubectl -n eventing-test attach curl -it
```
Once logged in, you'll see output similar to:
```
Defaulting container name to curl.
Use 'kubectl describe pod/curl -n eventing-test' to see all of the containers in this pod.
If you don't see a command prompt, try pressing enter.
[ root@curl:/ ]$
```
Now, generate an event using curl. This needs some extra definitions and requires the broker URL generated during the installation. This example sends a greeting to the broker:
```
curl -v "http://broker-ingress.knative-eventing.svc.cluster.local/eventing-test/default" \
  -X POST \
  -H "Ce-Id: say-hello" \
  -H "Ce-Specversion: 1.0" \
  -H "Ce-Type: greeting" \
  -H "Ce-Source: not-sendoff" \
  -H "Content-Type: application/json" \
  -d '{"msg":"Hello Knative!"}'
```
`Ce` is short for CloudEvent, which is the [standardized CloudEvents specification][9] that Knative follows. You also need to know the event ID (this is useful to verify it was delivered), the type, the source (which must specify that it is not a `sendoff` so that it doesn't go to the source defined in the sendoff trigger), and a message.
When you run the command, this should be the output (and you should receive a [202 Accepted][10] response):
```
> POST /eventing-test/default HTTP/1.1
> User-Agent: curl/7.35.0
> Host: broker-ingress.knative-eventing.svc.cluster.local
> Accept: */*
> Ce-Id: say-hello
> Ce-Specversion: 1.0
> Ce-Type: greeting
> Ce-Source: not-sendoff
> Content-Type: application/json
> Content-Length: 24
>
< HTTP/1.1 202 Accepted
< Date: Sun, 24 Jan 2021 22:25:25 GMT
< Content-Length: 0
```
The 202 means the trigger sent it to the **hello-display** consumer (because of the definition.)
Next, send a second definition to the **goodbye-display** consumer with this new curl command:
```
curl -v "http://broker-ingress.knative-eventing.svc.cluster.local/eventing-test/default" \
  -X POST \
  -H "Ce-Id: say-goodbye" \
  -H "Ce-Specversion: 1.0" \
  -H "Ce-Type: not-greeting" \
  -H "Ce-Source: sendoff" \
  -H "Content-Type: application/json" \
  -d '{"msg":"Goodbye Knative!"}'
```
This time, it is a `sendoff` and not a greeting based on the previous setup section's trigger definition. It is directed to the **goodbye-display** consumer.
Your output should look like this, with another 202 returned:
```
> POST /eventing-test/default HTTP/1.1
> User-Agent: curl/7.35.0
> Host: broker-ingress.knative-eventing.svc.cluster.local
> Accept: */*
> Ce-Id: say-goodbye
> Ce-Specversion: 1.0
> Ce-Type: not-greeting
> Ce-Source: sendoff
> Content-Type: application/json
> Content-Length: 26
>
< HTTP/1.1 202 Accepted
< Date: Sun, 24 Jan 2021 22:33:00 GMT
< Content-Length: 0
```
Congratulations, you sent two events!
Before moving on to the next section, exit the pod by typing **exit**.
### Verify the events
Now that the events have been sent, how do you know that the correct consumers received them? By going to each consumer and verifying it in the logs.
Start with the **hello-display** consumer::
```
$ kubectl -n eventing-test logs -l app=hello-display --tail=100
```
There isn't much running in this example cluster, so you should see only one event:
```
☁️  cloudevents.Event
Validation: valid
Context Attributes,
  specversion: 1.0
  type: greeting
  source: not-sendoff
  id: say-hello
  datacontenttype: application/json
Extensions,
  knativearrivaltime: 2021-01-24T22:25:25.760867793Z
Data,
  {
    "msg": "Hello Knative!"
  }
```
You've confirmed the **hello-display** consumer received the event! Now check the **goodbye-display** consumer and make sure the other message made it.
Start by running the same command but with **goodbye-display**:
```
$ kubectl -n eventing-test logs -l app=goodbye-display --tail=100
☁️  cloudevents.Event
Validation: valid
Context Attributes,
  specversion: 1.0
  type: not-greeting
  source: sendoff
  id: say-goodbye
  datacontenttype: application/json
Extensions,
  knativearrivaltime: 2021-01-24T22:33:00.515716701Z
Data,
  {
    "msg": "Goodbye Knative!"
  }
```
It looks like both events made it to their proper locations. Congratulations—you have officially worked with Knative eventing!
### Bonus round: Send an event to multiple consumers
So you sent events to each consumer using curl, but what if you want to send an event to both consumers? This uses a similar curl command but with some interesting changes. In the previous triggers, each one was defined with a different attribute. The greeting trigger had attribute `type`, and sendoff trigger had attribute `source`. This means you can make a curl call and send it to both consumers.
Here is a curl example of a definition for sending an event to both consumers:
```
curl -v "http://broker-ingress.knative-eventing.svc.cluster.local/eventing-test/default" \
  -X POST \
  -H "Ce-Id: say-hello-goodbye" \
  -H "Ce-Specversion: 1.0" \
  -H "Ce-Type: greeting" \
  -H "Ce-Source: sendoff" \
  -H "Content-Type: application/json" \
  -d '{"msg":"Hello Knative! Goodbye Knative!"}'
```
As you can see, the definition of this curl command changed to set the `source` for **goodbye-display** and the `type` for **hello-display**.
Here is sample output of what the events look like after they are sent.
**Output of the event being sent:**
```
> POST /eventing-test/default HTTP/1.1
> User-Agent: curl/7.35.0
> Host: broker-ingress.knative-eventing.svc.cluster.local
> Accept: */*
> Ce-Id: say-hello-goodbye
> Ce-Specversion: 1.0
> Ce-Type: greeting
> Ce-Source: sendoff
> Content-Type: application/json
> Content-Length: 41
>
< HTTP/1.1 202 Accepted
< Date: Sun, 24 Jan 2021 23:04:15 GMT
< Content-Length: 0
```
**Output of hello-display (showing two events):**
```
$ kubectl -n eventing-test logs -l app=hello-display --tail=100
☁️  cloudevents.Event
Validation: valid
Context Attributes,
  specversion: 1.0
  type: greeting
  source: not-sendoff
  id: say-hello
  datacontenttype: application/json
Extensions,
  knativearrivaltime: 2021-01-24T22:25:25.760867793Z
Data,
  {
    "msg": "Hello Knative!"
  }
☁️  cloudevents.Event
Validation: valid
Context Attributes,
  specversion: 1.0
  type: greeting
  source: sendoff
  id: say-hello-goodbye
  datacontenttype: application/json
Extensions,
  knativearrivaltime: 2021-01-24T23:04:15.036352685Z
Data,
  {
    "msg": "Hello Knative! Goodbye Knative!"
  }
```
**Output of goodbye-display (also with two events):**
```
$ kubectl -n eventing-test logs -l app=goodbye-display --tail=100
☁️  cloudevents.Event
Validation: valid
Context Attributes,
  specversion: 1.0
  type: not-greeting
  source: sendoff
  id: say-goodbye
  datacontenttype: application/json
Extensions,
  knativearrivaltime: 2021-01-24T22:33:00.515716701Z
Data,
  {
    "msg": "Goodbye Knative!"
  }
☁️  cloudevents.Event
Validation: valid
Context Attributes,
  specversion: 1.0
  type: greeting
  source: sendoff
  id: say-hello-goodbye
  datacontenttype: application/json
Extensions,
  knativearrivaltime: 2021-01-24T23:04:15.036352685Z
Data,
  {
    "msg": "Hello Knative! Goodbye Knative!"
  }
```
As you can see, the event went to both consumers based on your curl definition. If an event needs to be sent to more than one place, you can write definitions to send it to more than one consumer.
### Give it a try!
Internal eventing in cloud events is pretty easy to track if it's going to a predefined location of your choice. Enjoy seeing how far you can go with eventing in your cluster!
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/2/knative-eventing
作者:[Jessica Cherry][a]
选题:[lkxed][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/cherrybomb
[b]: https://github.com/lkxed
[1]: https://opensource.com/sites/default/files/lead-images/computer_space_graphic_cosmic.png
[2]: https://opensource.com/article/20/11/knative
[3]: https://opensource.com/resources/what-is-kubernetes
[4]: https://en.wikipedia.org/wiki/Cloud_native_computing
[5]: https://cloudevents.io/
[6]: https://github.com/Alynder/knative_eventing
[7]: https://minikube.sigs.k8s.io/docs/
[8]: https://www.redhat.com/sysadmin/use-curl-api
[9]: https://github.com/cloudevents/spec
[10]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/202

View File

@@ -1,261 +0,0 @@
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (Review of Three Hyperledger Tools Caliper, Cello and Avalon)
[#]: via: (https://www.linux.com/news/review-of-three-hyperledger-tools-caliper-cello-and-avalon/)
[#]: author: (Dan Brown https://training.linuxfoundation.org/announcements/review-of-three-hyperledger-tools-caliper-cello-and-avalon/)
Review of Three Hyperledger Tools Caliper, Cello and Avalon
======
_By Matt Zand_
#### **Recap**
In our previous article ([Review of Five popular Hyperledger DLTs- Fabric, Besu, Sawtooth, Iroha and Indy][1]), we discussed the following Hyperledger Distributed Ledger Technologies (DLTs).
1. Hyperledger Indy
2. Hyperledger Fabric
3. Hyperledger Iroha
4. Hyperledger Sawtooth
5. Hyperledger Besu
To continue our journey, in this article we discuss three Hyperledger tools (Hyperledger Caliper, Cello and Avalon) that act as great accessories for any of Hyperledger DLTs. It is worth mentioning that, as of this writing, all of three tools discussed in this article are at the incubation stage.
#### **Hyperledger Caliper**
Caliper is a benchmarking tool for measuring blockchain performance and is written in [JavaScript][2]. It utilizes the following four performance indicators: success rate, Transactions Per Second (or transaction throughput), transaction latency, and resource utilization. Specifically, it is designed to perform benchmarks on a deployed smart contract, enabling the analysis of said four indicators on a blockchain network while smart contract is being used.
Caliper is a unique general tool and has become a useful reference for enterprises to measure the performance of their distributed ledgers. The Caliper project will be one of the most important tools to use along with other Hyperledger projects (even in [Quorum][3] or [Ethereum][4] projects since it also supports those types of blockchains). It offers different connectors to various blockchains, which gives it greater power and usability. Likewise, based on its documentation, Caliper is ideal for:
* Application developers interested in running performance tests for their smart contracts
* System architects interested in investigating resource constraints during test loads
To better understand how Caliper works, one should start with its architecture. Specifically, to use it, a user should start with defining the following configuration files:
* A **benchmark** file defining the arguments of a benchmark workload
* A **blockchain** file specifying the necessary information, which helps to interact with the system being tested
* **Smart contracts** defining what contracts are going to be deployed
The above configuration files act as inputs for the Caliper CLI, which creates an admin client (acts as a superuser) and factory (being responsible for running test loads). Based on a chosen benchmark file, a client could be transacting with the system by adding or querying assets.
While testing is in progress, all transactions are saved. The statistics of these transactions are logged and stored. Further, a resource monitor logs the consumption of resources. All of this data is eventually aggregated into a single report. For more detailed discussion on its implementation, visit the link provided in the References section.
**Hyperledger Cello**
As blockchain applications eventually deployed at the enterprise level, developers had to do a lot of manual work when deploying/managing a blockchain. This job does not get any easier if multiple tenants need to access separate chains simultaneously. For instance, interacting with Hyperledger Fabric requires manual installation of each peer node on different servers, as well as setting up scripts (e.g., Docker-Composer) to start a Fabric network. Thus, to address said challenges while automating the process for developers, Hyperledger Cello got incubated. Cello brings the on-demand deployment model to blockchains and is written in the [Go language][5]. Cello is an automated application for deploying and managing blockchains in the form of plug-and-play, particularly for enterprises looking to integrate distributed ledger technologies.
Cello also provides a real-time dashboard for blockchain statuses, system utilization, chain code performance, and the configuration of blockchains. It currently supports Hyperledger Fabric. According to its documentation, Cello allows for:
* Provisioning customized blockchains instantly
* Maintaining a pool of running blockchains healthy without any need for manual operation
* Checking the systems status, scaling the chain numbers, changing resources, etc. through a dashboard
Likewise, according to its documentation, the major Cellos features are:
* Management of multiple blockchains (e.g., create, delete, and maintain health automatically)
* Almost instant response, even with hundreds of chains or nodes
* Support for customized blockchains request (e.g., size, consensus) — currently, there is support for Hyperledger Fabric
* Support for a native Docker host or a Swarm host as the compute nodes
* Support for heterogeneous architecture (e.g., z Systems, Power Systems, and x86) from bare-metal servers to virtual machines
* Extensible with monitoring, logging, and health features through employing additional components
According to its developers, Cellos architecture follows the principles of the [microservices][6], fault resilience, and scalability. In particular, Cello has three functional layers:
* **The access layer**, which also includes web UI dashboards operated by users
* **The orchestration layer**, which on receiving the request from the access layer, makes a call to the agents to operate the blockchain resources
* **The agent layer**, which embodies real workers that interact with underlying infrastructures like Docker, [Swarm][7], or Kubernetes
According to its documentation, each layer should maintain stable APIs for upper layers to achieve pluggability without changing the upper-layer code. For more detailed discussion on its implementation, visit the link provided in the References section.
**Hyperledger Avalon**
To boost the performance of blockchain networks, developers decided to store non-essential data into off-the-chain databases. While this approach improved blockchain scalability, it led to some confidentiality issues. So, the community was in search of an approach that can achieve scalability and confidentiality goals at once; thus, it led to the incubation of Avalon. Hyperledger Avalon (formerly Trusted Compute Framework) enables privacy in blockchain transactions, shifting heavy processing from a main blockchain to trusted off-chain computational resources in order to improve scalability and latency, and to support attested Oracles.
The Trusted Compute Specification was designed to assist developers gain the benefits of computational trust and to overcome its drawbacks. In the case of the Avalon, a blockchain is used to enforce execution policies and ensure transaction auditability, while associated off-chain trusted computational resources execute transactions. By utilizing trusted off-chain computational resources, a developer can accelerate throughput and improve data privacy. By using Hyperledger Avalon in a distributed ledger, we can:
* Maintain a registry of the trusted workers (including their attestation info)
* Provide a mechanism for submitting work orders from a client(s) to a worker
* Preserve a log of work order receipts and acknowledgments
To put it simply, the off-chain parts related to the main-network are  executing the transactions with the help of trusted compute resources. What guarantees the enforcement of confidentiality along with the integrity of execution is the Trusted Compute option with the following features:
* Trusted Execution Environment (TEE)
* MultiParty Commute (MPC)
* Zero-Knowledge Proofs (ZKP)
By means of Trusted Execution Environments, a developer can enhance the integrity of the link in the off-chain and on-chain execution. Intels SGX play is a known example of TEEs, which have capabilities such as code verification, attestation verification, and execution isolation which allows the creation of a trustworthy link between main-chain and off-chain compute resources. For more detailed discussion on its implementation, visit the link provided in the References section.
**Note- Hyperledger Explorer Tool (deprecated)**
Hyperledger Explorer, in a nutshell, provides a dashboard for peering into block details which are primarily written in JavaScript. Hyperledger Explorer is known to all developers and system admins that have done work in Hyperledger in past few years. In spite of its great features and popularity, Hyperledger announced last year that they no longer maintain it. So this tool is deprecated.
**Next Article**
In our upcoming article, we move on covering the below four Hyperledger libraries:
1. Hyperledger Aries
2. Hyperledger Quilt
3. Hyperledger Ursa
4. Hyperledger Transact
**Summary**
To recap, we covered three Hyperledger tools (Caliper, Cello and Avalon) in this article. We started off by explaining that Hyperledger Caliper is designed to perform benchmarks on a deployed smart contract, enabling the analysis of four indicators (like success rate or transaction throughout) on a blockchain network while smart contract is being used. Next, we learned that Hyperledger Cello is an automated application for deploying and managing blockchains in the form of plug-and-play, particularly for enterprises looking to integrate distributed ledger technologies. At last, Hyperledger Avalon enables privacy in blockchain transactions, shifting heavy processing from a main blockchain to trusted off-chain computational resources in order to improve scalability and latency, and to support attested Oracles.
** References**
For more references on all Hyperledger projects, libraries and tools, visit the below documentation links:
1. [Hyperledger Indy Project][8]
2. [Hyperledger Fabric Project][9]
3. [Hyperledger Aries Library][10]
4. [Hyperledger Iroha Project][11]
5. [Hyperledger Sawtooth Project][12]
6. [Hyperledger Besu Project][13]
7. [Hyperledger Quilt Library][14]
8. [Hyperledger Ursa Library][15]
9. [Hyperledger Transact Library][16]
10. [Hyperledger Cactus Project][17]
11. [Hyperledger Caliper Tool][18]
12. [Hyperledger Cello Tool][19]
13. [Hyperledger Explorer Tool][20]
14. [Hyperledger Grid (Domain Specific)][21]
15. [Hyperledger Burrow Project][22]
16. [Hyperledger Avalon Tool][23]
**Resources**
* Free Training Courses from The Linux Foundation &amp; Hyperledger
* [Blockchain: Understanding Its Uses and Implications (LFS170)][24]
* [Introduction to Hyperledger Blockchain Technologies (LFS171)][25]
* [Introduction to Hyperledger Sovereign Identity Blockchain Solutions: Indy, Aries &amp; Ursa (LFS172)][26]
* [Becoming a Hyperledger Aries Developer (LFS173)][27]
* [Hyperledger Sawtooth for Application Developers (LFS174)][28]
* eLearning Courses from The Linux Foundation &amp; Hyperledger
* [Hyperledger Fabric Administration (LFS272)][29]
* [Hyperledger Fabric for Developers (LFD272)][30]
* Certification Exams from The Linux Foundation &amp; Hyperledger
* [Certified Hyperledger Fabric Administrator (CHFA)][31]
* [Certified Hyperledger Fabric Developer (CHFD)][32]
* [Hands-On Smart Contract Development with Hyperledger Fabric V2][33] Book by Matt Zand and others.
* [Essential Hyperledger Sawtooth Features for Enterprise Blockchain Developers][34]
* [Blockchain Developer Guide- How to Install Hyperledger Fabric on AWS][35]
* [Blockchain Developer Guide- How to Install and work with Hyperledger Sawtooth][36]
* [Intro to Blockchain Cybersecurity (Coding Bootcamps)][37]
* [Intro to Hyperledger Sawtooth for System Admins (Coding Bootcamps)][38]
* [Blockchain Developer Guide- How to Install Hyperledger Iroha on AWS][39]
* [Blockchain Developer Guide- How to Install Hyperledger Indy and Indy CLI on AWS][40]
* [Blockchain Developer Guide- How to Configure Hyperledger Sawtooth Validator and REST API on AWS][41]
* [Intro blockchain development with Hyperledger Fabric (Coding Bootcamps)][42]
* [How to build DApps with Hyperledger Fabric][43]
* [Blockchain Developer Guide- How to Build Transaction Processor as a Service and Python Egg for Hyperledger Sawtooth][44]
* [Blockchain Developer Guide- How to Create Cryptocurrency Using Hyperledger Iroha CLI][45]
* [Blockchain Developer Guide- How to Explore Hyperledger Indy Command Line Interface][46]
* [Blockchain Developer Guide- Comprehensive Blockchain Hyperledger Developer Guide from Beginner to Advance Level][47]
* [Blockchain Management in Hyperledger for System Admins][48]
* [Hyperledger Fabric for Developers (Coding Bootcamps)][49]
* [Free White Papers from Hyperledger][50]
* [Free Webinars from Hyperledger][51]
* [Hyperledger Wiki][52]
**About the Author**
**Matt Zand** is a serial entrepreneur and the founder of 3 tech startups: [DC Web Makers][53], [Coding Bootcamps][54] and [High School Technology Services][55]. He is a leading author of [Hands-on Smart Contract Development with Hyperledger Fabric][33] book by OReilly Media. He has written more than 100 technical articles and tutorials on blockchain development for Hyperledger, Ethereum and Corda R3 platforms at sites such as IBM, SAP, Alibaba Cloud, Hyperledger, The Linux Foundation, and more. As a public speaker, he has presented webinars at many Hyperledger communities across USA and Europe.. At DC Web Makers, he leads a team of blockchain experts for consulting and deploying enterprise decentralized applications. As chief architect, he has designed and developed blockchain courses and training programs for Coding Bootcamps. He has a masters degree in business management from the University of Maryland. Prior to blockchain development and consulting, he worked as senior web and mobile App developer and consultant, angel investor, business advisor for a few startup companies. You can connect with him on LI: <https://www.linkedin.com/in/matt-zand-64047871>
The post [Review of Three Hyperledger Tools Caliper, Cello and Avalon][56] appeared first on [Linux Foundation Training][57].
--------------------------------------------------------------------------------
via: https://www.linux.com/news/review-of-three-hyperledger-tools-caliper-cello-and-avalon/
作者:[Dan Brown][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://training.linuxfoundation.org/announcements/review-of-three-hyperledger-tools-caliper-cello-and-avalon/
[b]: https://github.com/lujun9972
[1]: https://training.linuxfoundation.org/announcements/review-of-five-popular-hyperledger-dlts-fabric-besu-sawtooth-iroha-and-indy/
[2]: https://learn.coding-bootcamps.com/p/learn-javascript-web-development-by-examples
[3]: https://coding-bootcamps.com/blog/introduction-to-quorum-blockchain-development.html
[4]: https://myhsts.org/blog/ethereum-dapp-with-evm-remix-golang-truffle-and-solidity-part1.html
[5]: https://learn.coding-bootcamps.com/p/learn-go-programming-language-by-examples
[6]: https://blockchain.dcwebmakers.com/blog/comprehensive-guide-for-migration-from-monolithic-to-microservices-architecture.html
[7]: https://coding-bootcamps.com/blog/how-to-work-with-ethereum-swarm-storage.html
[8]: https://www.hyperledger.org/use/hyperledger-indy
[9]: https://www.hyperledger.org/use/fabric
[10]: https://www.hyperledger.org/projects/aries
[11]: https://www.hyperledger.org/projects/iroha
[12]: https://www.hyperledger.org/projects/sawtooth
[13]: https://www.hyperledger.org/projects/besu
[14]: https://www.hyperledger.org/projects/quilt
[15]: https://www.hyperledger.org/projects/ursa
[16]: https://www.hyperledger.org/projects/transact
[17]: https://www.hyperledger.org/projects/cactus
[18]: https://www.hyperledger.org/projects/caliper
[19]: https://www.hyperledger.org/projects/cello
[20]: https://www.hyperledger.org/projects/explorer
[21]: https://www.hyperledger.org/projects/grid
[22]: https://www.hyperledger.org/projects/hyperledger-burrow
[23]: https://www.hyperledger.org/projects/avalon
[24]: https://training.linuxfoundation.org/training/blockchain-understanding-its-uses-and-implications/
[25]: https://training.linuxfoundation.org/training/blockchain-for-business-an-introduction-to-hyperledger-technologies/
[26]: https://training.linuxfoundation.org/training/introduction-to-hyperledger-sovereign-identity-blockchain-solutions-indy-aries-and-ursa/
[27]: https://training.linuxfoundation.org/training/becoming-a-hyperledger-aries-developer-lfs173/
[28]: https://training.linuxfoundation.org/training/hyperledger-sawtooth-application-developers-lfs174/
[29]: https://training.linuxfoundation.org/training/hyperledger-fabric-administration-lfs272/
[30]: https://training.linuxfoundation.org/training/hyperledger-fabric-for-developers-lfd272/
[31]: https://training.linuxfoundation.org/certification/certified-hyperledger-fabric-administrator-chfa/
[32]: https://training.linuxfoundation.org/certification/certified-hyperledger-fabric-developer/
[33]: https://www.oreilly.com/library/view/hands-on-smart-contract/9781492086116/
[34]: https://weg2g.com/application/touchstonewords/article-essential-hyperledger-sawtooth-features-for-enterprise-blockchain-developers.php
[35]: https://myhsts.org/tutorial-learn-how-to-install-blockchain-hyperledger-fabric-on-amazon-web-services.php
[36]: https://myhsts.org/tutorial-learn-how-to-install-and-work-with-blockchain-hyperledger-sawtooth.php
[37]: https://learn.coding-bootcamps.com/p/learn-how-to-secure-blockchain-applications-by-examples
[38]: https://learn.coding-bootcamps.com/p/introduction-to-hyperledger-sawtooth-for-system-admins
[39]: https://myhsts.org/tutorial-learn-how-to-install-blockchain-hyperledger-iroha-on-amazon-web-services.php
[40]: https://myhsts.org/tutorial-learn-how-to-install-blockchain-hyperledger-indy-on-amazon-web-services.php
[41]: https://myhsts.org/tutorial-learn-how-to-configure-hyperledger-sawtooth-validator-and-rest-api-on-aws.php
[42]: https://learn.coding-bootcamps.com/p/live-and-self-paced-blockchain-development-with-hyperledger-fabric
[43]: https://learn.coding-bootcamps.com/p/live-crash-course-for-building-dapps-with-hyperledger-fabric
[44]: https://myhsts.org/tutorial-learn-how-to-build-transaction-processor-as-a-service-and-python-egg-for-hyperledger-sawtooth.php
[45]: https://myhsts.org/tutorial-learn-how-to-work-with-hyperledger-iroha-cli-to-create-cryptocurrency.php
[46]: https://myhsts.org/tutorial-learn-how-to-work-with-hyperledger-indy-command-line-interface.php
[47]: https://myhsts.org/tutorial-comprehensive-blockchain-hyperledger-developer-guide-for-all-professional-programmers.php
[48]: https://learn.coding-bootcamps.com/p/learn-blockchain-development-with-hyperledger-by-examples
[49]: https://learn.coding-bootcamps.com/p/hyperledger-blockchain-development-for-developers
[50]: https://www.hyperledger.org/learn/white-papers
[51]: https://www.hyperledger.org/learn/webinars
[52]: https://wiki.hyperledger.org/
[53]: https://blockchain.dcwebmakers.com/
[54]: http://coding-bootcamps.com/
[55]: https://myhsts.org/
[56]: https://training.linuxfoundation.org/announcements/review-of-three-hyperledger-tools-caliper-cello-and-avalon/
[57]: https://training.linuxfoundation.org/

View File

@@ -1,82 +0,0 @@
[#]: subject: (AIOps vs. MLOps: What's the difference?)
[#]: via: (https://opensource.com/article/21/2/aiops-vs-mlops)
[#]: author: (Lauren Maffeo https://opensource.com/users/lmaffeo)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
AIOps vs. MLOps: What's the difference?
======
Break down the differences between these disciplines to learn how you
should use them in your open source project.
![Brick wall between two people, a developer and an operations manager][1]
In late 2019, O'Reilly hosted a survey on artificial intelligence [(AI) adoption in the enterprise][2]. The survey broke respondents into two stages of adoption: Mature and Evaluation.
When asked what's holding back their AI adoption, those in the latter category most often cited company culture. Trouble identifying good use cases for AI wasn't far behind.
![Bottlenecks to AI adoption][3]
[AI adoption in the enterprise 2020][2] (O'Reilly, ©2020)
MLOps, or machine learning operations, is increasingly positioned as a solution to these problems. But that leaves a question: What _is_ MLOps?
It's fair to ask for two key reasons. This discipline is new, and it's often confused with a sister discipline that's equally important yet distinctly different: Artificial intelligence operations, or AIOps.
Let's break down the key differences between these two disciplines. This exercise will help you decide how to use them in your business or open source project.
### What is AIOps?
[AIOps][4] is a series of multi-layered platforms that automate IT to make it more efficient. Gartner [coined the term][5] in 2017, which emphasizes how new this discipline is. (Disclosure: I worked for Gartner for four years.)
At its best, AIOps allows teams to improve their IT infrastructure by using big data, advanced analytics, and machine learning techniques. That first item is crucial given the mammoth amount of data produced today.
When it comes to data, more isn't always better. In fact, many business leaders say they receive so much data that it's [increasingly hard][6] for them to collect, clean, and analyze it to find insights that can help their businesses.
This is where AIOps comes in. By helping DevOps and data operations (DataOps) teams choose what to automate, from development to production, this discipline [helps open source teams][7] predict performance problems, do root cause analysis, find anomalies, [and more][8].
### What is MLOps?
MLOps is a multidisciplinary approach to managing machine learning algorithms as ongoing products, each with its own continuous lifecycle. It's a discipline that aims to build, scale, and deploy algorithms to production consistently. 
Think of MLOps as DevOps applied to machine learning pipelines. [It's a collaboration][9] between data scientists, data engineers, and operations teams. Done well, it gives members of all teams more shared clarity on machine learning projects.
MLOps has obvious benefits for data science and data engineering teams. Since members of both teams sometimes work in silos, using shared infrastructure boosts transparency.
But MLOps can benefit other colleagues, too. This discipline offers the ops side more autonomy over regulation.
As an increasing number of businesses start using machine learning, they'll come under more scrutiny from the government, media, and public. This is especially true of machine learning in highly regulated industries like healthcare, finance, and autonomous vehicles.
Still skeptical? Consider that just [13% of data science projects make it to production][10]. The reasons are outside this article's scope. But, like AIOps helps teams automate their tech lifecycles, MLOps helps teams choose which tools, techniques, and documentation will help their models reach production.
When applied to the right problems, AIOps and MLOps can both help teams hit their production goals. The trick is to start by answering this question:
### What do you want to automate? Processes or machines?
When in doubt, remember: AIOps automates machines while MLOps standardizes processes. If you're on a DevOps or DataOps team, you can—and should—consider using both disciplines. Just don't confuse them for the same thing.
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/2/aiops-vs-mlops
作者:[Lauren Maffeo][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/lmaffeo
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/devops_confusion_wall_questions.png?itok=zLS7K2JG (Brick wall between two people, a developer and an operations manager)
[2]: https://www.oreilly.com/radar/ai-adoption-in-the-enterprise-2020/
[3]: https://opensource.com/sites/default/files/uploads/oreilly_bottlenecks-with-maturity.png (Bottlenecks to AI adoption)
[4]: https://www.bmc.com/blogs/what-is-aiops/
[5]: https://www.appdynamics.com/topics/what-is-ai-ops
[6]: https://www.millimetric.ai/2020/08/10/data-driven-to-madness-what-to-do-when-theres-too-much-data/
[7]: https://opensource.com/article/20/8/aiops-devops-itsm
[8]: https://thenewstack.io/how-aiops-conquers-performance-gaps-on-big-data-pipelines/
[9]: https://medium.com/@ODSC/what-are-mlops-and-why-does-it-matter-8cff060d4067
[10]: https://venturebeat.com/2019/07/19/why-do-87-of-data-science-projects-never-make-it-into-production/

View File

@@ -1,192 +0,0 @@
[#]: subject: "Navigate your FreeDOS system"
[#]: via: "https://opensource.com/article/21/2/freedos-dir"
[#]: author: "Kevin O'Brien https://opensource.com/users/ahuka"
[#]: collector: "lkxed"
[#]: translator: " "
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
Navigate your FreeDOS system
======
Master the DIR command to navigate your way around FreeDOS.
![A map with a route highlighted][1]
[FreeDOS][2] is an open source implementation of DOS. It's not a remix of Linux, and it is compatible with the operating system that introduced many people to personal computing. This makes it an important resource for running legacy applications, playing retro games, updating firmware on motherboards, and experiencing a little bit of living computer history. In this article, I'll look at some of the essential commands used to navigate a FreeDOS system.
### Change your current directory with CD
When you first boot FreeDOS, you're "in" the root directory, which is called `C:\`. This represents the foundation of your filesystem, specifically the system hard drive. It's labeled with a `C` because, back in the old days of MS-DOS and PC-DOS, there were always `A` and `B` floppy drives, making the physical hard drive the third drive by default. The convention has been retained to this day in FreeDOS and the operating system that grew out of MS-DOS, Windows.
There are many reasons not to work exclusively in your root directory. First of all, there are limitations to the FAT filesystem that would make that impractical at scale. Secondly, it would make for a very poorly organized filesystem. So it's common to make new directories (or "folders," as we often refer to them) to help keep your work tidy. To access these files easily, it's convenient to change your working directory.
The FreeDOS `CD` command changes your current working subdirectory to another subdirectory. Imagine a computer with the following directory structure:
```
C:\  
\LETTERS\  
  \LOVE\
  \BUSINESS\
\DND\
\MEMOS\  
\SCHOOL\
```
You start in the `C:\` directory, so to navigate to your love letter directory, you can use `CD` :
```
C:\>CD \LETTERS\LOVE\
```
To navigate to your `\LETTERS\BUSINESS` directory, you must specify the path to your business letters from a common fixed point on your filesystem. The most reliable starting location is `C:\`, because it's where *everything* on your computer is stored.
```
C:\LETTERS\LOVE\>CD C:\LETTERS\BUSINESS
```
#### Navigating with dots
There's a useful shortcut for navigating your FreeDOS system, which takes the form of dots. Two dots (`..` ) tell FreeDOS you want to move "back" or "down" in your directory tree. For instance, the `LETTERS` directory in this example system contains one subdirectory called `LOVE` and another called `BUSINESS`. If you're in `LOVE` currently, and you want to step back and change over to `BUSINESS`, you can just use two dots to represent that move:
```
C:\LETTERS\LOVE\>CD ..\BUSINESS
C:\LETTERS\BUSINESS\>
```
To get all the way back to your root directory, just use the right number of dots:
```
C:\LETTERS\BUSINESS\: CD ..\..
C:\>
```
#### Navigational shortcuts
There are some shortcuts for navigating directories, too.
To get back to the root directory from wherever you are:
```
C:\LETTERS\BUSINESS\>CD \
C:\>
```
### List directory contents with DIR
The `DIR` command displays the contents of a subdirectory, but it can also function as a search command. This is one of the most used commands in FreeDOS, and learning to use it properly is a great time saver.
`DIR` displays the contents of the current working subdirectory, and with an optional path argument, it displays the contents of some other subdirectory:
```
C:\LETTERS\BUSINESS\>DIR
MTG_CARD    TXT  1344 12-29-2020  3:06p
NON         TXT   381 12-31-2020  8:12p
SOMUCHFO    TXT   889 12-31-2020  9:36p
TEST        BAT    32 01-03-2021 10:34a
```
#### Attributes
With a special attribute argument, you can use `DIR` to find and filter out certain kinds of files. There are 10 attributes you can specify:
| - | - |
| :- | :- |
| H | Hidden |
| -H | Not hidden |
| S | System |
| -S | Not system |
| A | Archivable files |
| -A | Already archived files |
| R | Read-only files |
| -R | Not read-only (i.e., editable and deletable) files |
| D | Directories only, no files |
| -D | Files only, no directories |
These special designators are denoted with `/A:` followed by the attribute letter. You can enter as many attributes as you like, in order, without leaving a space between them. For instance, to view only hidden directories:
```
C:\MEMOS\>DIR /A:HD
.OBSCURE    <DIR>  01-08-2021 10:10p
```
#### Listing in order
You can also display the results of your `DIR` command in a specific order. The syntax for this is very similar to using attributes. You leave a space after the `DIR` command or after any other switches, and enter `/O:` followed by a selection. There are 12 possible selections:
| - | - |
| :- | :- |
| N | Alphabetical order by file name |
| -N | Reverse alphabetical order by file name |
| E | Alphabetical order by file extension |
| -E | Reverse alphabetical order by file extension |
| D | Order by date and time, earliest first |
| -D | Order by date and time, latest first |
| S | By size, increasing |
| -S | By size, decreasing |
| C | By DoubleSpace compression ratio, lowest to highest (version 6.0 only) |
| -C | By DoubleSpace compression ratio, highest to lowest (version 6.0 only) |
| G | Group directories before other files |
| -G | Group directories after other files |
To see your directory listing grouped by file extension:
```
C:\>DIR /O:E
TEST        BAT 01-10-2021 7:11a
TIMER       EXE 01-11-2021 6:06a
AAA         TXT 01-09-2021 4:27p
```
This returns a list of files in alphabetical order of file extension.
If you're looking for a file you were working on yesterday, you can order by modification time:
```
C:\>DIR /O:-D
AAA         TXT 01-09-2021 4:27p
TEST        BAT 01-10-2021 7:11a
TIMER       EXE 01-11-2021 6:06a
```
If you need to clean up your hard drive because you're running out of space, you can order your list by file size, and so on.
#### Multiple arguments
You can use multiple arguments in a `DIR` command to achieve fairly complex results. Remember that each argument has to be separated from its neighbors by a blank space on each side:
```
C:\>DIR /A:A /O:D /P
```
This command selects only those files that have not yet been backed up (`/A:A` ), orders them by date, beginning with the oldest (`/O:D` ), and displays the results on your monitor one page at a time (`/P` ). So you can really do some slick stuff with the `DIR` command once you've mastered these arguments and switches.
### Terminology
In case you were wondering, anything that modifies a command is an argument.
If it has a slash in front, it is a switch. So all switches are also arguments, but some arguments (for example, a file path) are not switches.
### Better navigation in FreeDOS
FreeDOS can be very different from what you're used to if you're used to Windows or macOS, and it can be just different enough if you're used to Linux. A little practice goes a long way, though, so try some of these on your own. You can always get a help message with the `/?` switch. The best way to get comfortable with these commands is to practice using them.
*Some of the information in this article was previously published in [DOS lesson 12: Expert DIR use][3] (CC BY-SA 4.0).*
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/2/freedos-dir
作者:[Kevin O'Brien][a]
选题:[lkxed][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/ahuka
[b]: https://github.com/lkxed
[1]: https://opensource.com/sites/default/files/lead-images/map_route_location_gps_path.png
[2]: https://www.freedos.org/
[3]: https://www.ahuka.com/dos-lessons-for-self-study-purposes/dos-lesson-12-expert-dir-use/

View File

@@ -1,58 +0,0 @@
[#]: subject: (Build your own technology on Linux)
[#]: via: (https://opensource.com/article/21/2/linux-technology)
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
Build your own technology on Linux
======
Linux puts you in charge of your own technology so you can use it any
way you want.
![Someone wearing a hardhat and carrying code ][1]
In 2021, there are more reasons why people love Linux than ever before. In this series, I'll share 21 different reasons to use Linux. Linux empowers its users to build their own tools.
There's a persistent myth that tech companies must "protect" their customers from the many features of their technology. Sometimes, companies put restrictions on their users for fear of unexpected breakage, and other times they expect users to pay extra to unlock features. I love an operating system that protects me from stupid mistakes, but I want to know without a doubt that there's a manual override switch somewhere. I want to be able to control my own experience on my own computer. Whether I'm using Linux for work or my hobbies, that's precisely what it does for me. It puts me in charge of the technology I've chosen to use.
### Customizing your tools
It's hard for a business, even when its public face is the image of a "quirky revolutionary," to deal with the fact that reality is actually quite diverse. Literally everybody on the planet uses a computer differently than the next person. We all have our habits; we have artifacts of good and bad computer training; we have our interest levels, our distractions, and our individual goals.
No matter what a company anticipates, there's no way to construct the ideal environment to please each and every potential user. And it's a tall order to expect a business to even attempt that. You might even think it's an unreasonable demand to have a custom tool for every individual.
But we're living in the future, it's a high-tech world, and the technology that empowers users to design and use their own tools has been around for decades. You can witness early Unix users stringing together commands on old [_Computer Chronicles_][2] episodes way back in 1985. Today, you see it in spreadsheet applications, possibly the most well-used and malleable (and unintentional) prototype engines available. From business forms to surveys to games to video encoder frontends, I've seen everyday users claiming to have "no programming skills" design spreadsheets that rival applications developed and sold by software companies. This is the kind of creativity that technology should foster and encourage, and I think it's the way computing is heading the more that _open source_ principles become an expectation.
Today, Linux delivers the same power: the power to construct your own utilities and offer them to other users in a portable and adaptable format. Whether you work in Bash, Python, or LibreOffice Calc, Linux invites you to build tools that make your life easier.
### Services
I believe one of the missing components of the modern computing experience is connectedness. That seems like a crazy thing to assert in the 21st century when we have social networks that claim to bring people together like never before. But social networks have always felt like more like a chaperoned prom than a casual hangout. You go to a place where you're expected to socialize, and you do what's expected of you, but deep down, you'd rather just invite your friends over to watch some movies and play some games.
The deficiency of modern computing platforms is that this casual level of sharing our digital life isn't easy. In fact, it's really difficult on most computers. While we're still a long away from a great selection of sharable applications, Linux is nevertheless built for sharing. It doesn't try to block your path when you open a port to invite your friends to connect to a shared application like [Drawpile][3] or [Maptool][4]. On the contrary, it has [tools specifically to make sharing _easy_][5].
### Stand back; I'm doing science!
Linux is a platform for makers, creators, and developers. It's part of its core tenet to let its users explore and to ensure that the user remains in control of their system. Linux offers you an open source environment and an [open studio][6]. All you have to do is take advantage of it.
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/2/linux-technology
作者:[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/build_structure_tech_program_code_construction.png?itok=nVsiLuag (Someone wearing a hardhat and carrying code )
[2]: https://archive.org/details/UNIX1985
[3]: https://opensource.com/article/20/3/drawpile
[4]: https://opensource.com/article/18/5/maptool
[5]: https://opensource.com/article/19/7/make-linux-stronger-firewalls
[6]: https://www.redhat.com/en/about/open-studio

View File

@@ -1,222 +0,0 @@
[#]: subject: (Getting started with COBOL development on Fedora Linux 33)
[#]: via: (https://fedoramagazine.org/getting-started-with-cobol-development-on-fedora-linux-33/)
[#]: author: (donnie https://fedoramagazine.org/author/donnie/)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
Getting started with COBOL development on Fedora Linux 33
======
![cobol_article_title_photo][1]
Though its popularity has waned, COBOL is still powering business critical operations within many major organizations. As the need to update, upgrade and troubleshoot these applications grows, so may the demand for anyone with COBOL development knowledge.
Fedora 33 represents an excellent platform for COBOL development.
This article will detail how to install and configure tools, as well as compile and run a COBOL program.
### Installing and configuring tools
GnuCOBOL is a free and open modern compiler maintained by volunteer developers. To install, open a terminal and execute the following command:
```
# sudo dnf -y install gnucobol
```
Once completed, execute this command to verify that GnuCOBOL is ready for work:
```
# cobc -v
```
You should see version information and build dates. Dont worry if you see the error “no input files”. We will create a COBOL program file with the Vim text editor in the following steps.
Fedora ships with a minimal version of Vim, but it would be nice to have some of the extra features that the full version can offer (such as COBOL syntax highlighting). Run the command below to install Vim-enhanced, which will overwrite Vim-minimal:
```
# sudo dnf -y install vim-enhanced
```
### Writing, Compiling, and Executing COBOL programs
At this point, you are ready to write a COBOL program. For this example, I am set up with username _fedorauser_ and I will create a folder under my home directory to store my COBOL programs. I called mine _cobolcode_.
```
# mkdir /home/fedorauser/cobolcode
# cd /home/fedorauser/cobolcode
```
Now we can create and open a new file to enter our COBOL source program. Ill call it _helloworld.cbl_.
```
# vim helloworld.cbl
```
You should now have the blank file open in Vim, ready to edit. This will be a simple program that does nothing except print out a message to our terminal.
Enable “insert” mode in vim by pressing the “i” key, and key in the text below. Vim will assist with placement of your code sections. This can be very helpful since every character space in a COBOL file has a purpose (its a digital representation of the physical cards that developers would complete and feed into the computer).
```
IDENTIFICATION DIVISION.
PROGRAM-ID. HELLO-WORLD.
*simple helloworld program.
PROCEDURE DIVISION.
DISPLAY '##################################'.
DISPLAY '#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#'.
DISPLAY '#!!!!!!!!!!FEDORA RULES!!!!!!!!!!#'.
DISPLAY '#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#'.
DISPLAY '##################################'.
STOP RUN.
```
You can now press the “ESC” key to exit insert mode, and key in “:x” to save and close the file.
Compile the program by keying in the following:
```
# cobc -x helloworld.cbl
```
It should complete quickly with return status: 0. Key in “ls” to view the contents of your current directory. You should see your original _helloworld.cbl_ file, as well as a new file simply named _helloworld_.
Execute the COBOL program.
```
# ./helloworld
```
If you see your text output without errors, then you have sucessfully compiled and executed the program!
![][2]
Now that we have the basics of writing, compiling, and running a COBOL program, lets try one that does something a little more interesting.
The following program will generate the Fibonacci sequence given your input. Use Vim to create a file called _fib.cbl_ and input the text below:
```
******************************************************************
* Author: Bryan Flood
* Date: 25/10/2018
* Purpose: Compute Fibonacci Numbers
* Tectonics: cobc
******************************************************************
IDENTIFICATION DIVISION.
PROGRAM-ID. FIB.
DATA DIVISION.
FILE SECTION.
WORKING-STORAGE SECTION.
01 N0 BINARY-C-LONG VALUE 0.
01 N1 BINARY-C-LONG VALUE 1.
01 SWAP BINARY-C-LONG VALUE 1.
01 RESULT PIC Z(20)9.
01 I BINARY-C-LONG VALUE 0.
01 I-MAX BINARY-C-LONG VALUE 0.
01 LARGEST-N BINARY-C-LONG VALUE 92.
PROCEDURE DIVISION.
*> THIS IS WHERE THE LABELS GET CALLED
PERFORM MAIN
PERFORM ENDFIB
GOBACK.
*> THIS ACCEPTS INPUT AND DETERMINES THE OUTPUT USING A EVAL STMT
MAIN.
DISPLAY "ENTER N TO GENERATE THE FIBONACCI SEQUENCE"
ACCEPT I-MAX.
EVALUATE TRUE
WHEN I-MAX > LARGEST-N
PERFORM INVALIDN
WHEN I-MAX > 2
PERFORM CASEGREATERTHAN2
WHEN I-MAX = 2
PERFORM CASE2
WHEN I-MAX = 1
PERFORM CASE1
WHEN I-MAX = 0
PERFORM CASE0
WHEN OTHER
PERFORM INVALIDN
END-EVALUATE.
STOP RUN.
*> THE CASE FOR WHEN N = 0
CASE0.
MOVE N0 TO RESULT.
DISPLAY RESULT.
*> THE CASE FOR WHEN N = 1
CASE1.
PERFORM CASE0
MOVE N1 TO RESULT.
DISPLAY RESULT.
*> THE CASE FOR WHEN N = 2
CASE2.
PERFORM CASE1
MOVE N1 TO RESULT.
DISPLAY RESULT.
*> THE CASE FOR WHEN N > 2
CASEGREATERTHAN2.
PERFORM CASE1
PERFORM VARYING I FROM 1 BY 1 UNTIL I = I-MAX
ADD N0 TO N1 GIVING SWAP
MOVE N1 TO N0
MOVE SWAP TO N1
MOVE SWAP TO RESULT
DISPLAY RESULT
END-PERFORM.
*> PROVIDE ERROR FOR INVALID INPUT
INVALIDN.
DISPLAY 'INVALID N VALUE. THE PROGRAM WILL NOW END'.
*> END THE PROGRAM WITH A MESSAGE
ENDFIB.
DISPLAY "THE PROGRAM HAS COMPLETED AND WILL NOW END".
END PROGRAM FIB.
```
As before, hit the “ESC” key to exit insert mode, and key in “:x” to save and close the file.
Compile the program:
```
# cobc -x fib.cbl
```
Now execute the program:
```
# ./fib
```
The program will ask for you to input a number, and will then generate Fibonocci output based upon that number.
![][3]
### Further Study
There are numerous resources available on the internet to consult, however vast amounts of knowledge reside only in legacy print. Keep an eye out for vintage COBOL guides when visiting used book stores and public libraries; you may find copies of endangered manuals at a rock-bottom prices!
It is also worth noting that helpful documentation was installed on your system when you installed GnuCOBOL. You can access them with these terminal commands:
```
# info gnucobol
# man cobc
# cobc -h
```
![][4]
--------------------------------------------------------------------------------
via: https://fedoramagazine.org/getting-started-with-cobol-development-on-fedora-linux-33/
作者:[donnie][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://fedoramagazine.org/author/donnie/
[b]: https://github.com/lujun9972
[1]: https://fedoramagazine.org/wp-content/uploads/2021/02/Screenshot-from-2021-02-09-17-20-21-816x384.png
[2]: https://fedoramagazine.org/wp-content/uploads/2021/02/Screenshot-from-2021-01-02-21-48-22-1024x576.png
[3]: https://fedoramagazine.org/wp-content/uploads/2021/02/Screenshot-from-2021-02-21-22-11-51-1024x598.png
[4]: https://fedoramagazine.org/wp-content/uploads/2021/02/image_50369281-1-1024x768.jpg

View File

@@ -1,113 +0,0 @@
[#]: subject: (Edit video on Linux with this Python app)
[#]: via: (https://opensource.com/article/21/2/linux-python-video)
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
Edit video on Linux with this Python app
======
Three years ago I chose Openshot as my Linux video editing software of
choice. See why it's still my favorite.
![video editing dashboard][1]
In 2021, there are more reasons why people love Linux than ever before. In this series, I'll share 21 different reasons to use Linux. Here's how I use Linux to edit videos.
Back in 2018, I wrote an article about the [state of Linux video editing][2], in which I chose an application called [Openshot][3] as my pick for the top hobbyist video editing software. Years later, and my choices haven't changed. Openshot remains a great little video editing application for Linux, and it's managed to make creating videos on Linux _boring_ in the best of ways.
Well, video editing may never become boring in the sense that no platform will ever get it perfect because part of the art of moviemaking is the constant improvement of image quality and visual trickery. Software and cameras will forever be pushing each other forward and forever catching up to one another. I've been editing video on Linux since 2008 at the very least, but back then, editing video was still generally mystifying to most people. Computer users have become familiar with what used to be advanced concepts since then, so video editing is taken for granted. And video editing on Linux, at the very least, is at the stage of getting an obvious shrug. Yes, of course, you can edit your videos on Linux.
### Installing Openshot
On Linux, you can install Openshot from your distribution's software repository.
On Fedora and similar:
```
`$ sudo dnf install openshot`
```
On Debian, Linux Mint, Elementary, and similar:
```
`$ sudo apt install openshot`
```
### Importing video
Without the politics of "not invented here" syndrome and corporate identity, Linux has the best codec support in the tech industry. With the right libraries, you can play nearly any video format on Linux. It's a liberating feeling for even a casual content creator, especially to anyone who's spent an entire day downloading plugins and converter applications in a desperate attempt to get a video format into their proprietary video editing software. Barring [un]expected leaps and bounds in camera technology, you generally don't have to do that on Linux. Openshot uses [ffmpeg][4] to import videos, so you can edit whatever format you need to edit.
![Importing into Openshot][5]
Import into Openshot
**Note**: When importing video, I prefer to standardize on the formats I use. It's fine to mix formats a little, but for consistency in behavior and to eliminate variables when troubleshooting, I convert any outliers in my source material to whatever the majority of my project uses. I prefer my source to be only lightly compressed when that's an option, so I can edit at a high quality and save compression for the final render.
### Auditioning footage
Once you've imported your video clips, you can preview each clip right in Openshot. To play a clip, right-click the clip and select **Preview file**. This option opens a playback window so you can watch your footage. This is a common task for a production with several takes of the same material.
When rummaging through a lot of footage, you can tag clips in Openshot to help you keep track of which ones are good and which ones you don't think you'll use, or what clip belongs to which scene, or any other meta-information you need to track. To tag a clip, right-click on it and select **File properties**. Add your tags to the **Tag** field.
![Tagging files in Openshot][6]
Tagging files in Openshot
### Add video to the timeline
Whether you have a script you're following, or you're just sorting through footage and finding a story, you eventually get a sense of how you think your video ought to happen. There are always myriad possibilities at this stage, and that's a good thing. It's why video editing is one of the single most influential stages of moviemaking. Will you start with a cold open _in media res_? Or maybe you want to start at the end and unravel your narrative to lead back up to that? Or are you a traditional story-teller, proudly beginning at the beginning? Whatever you decide now, you can always change later, so the most important thing is just to get started.
Getting started means putting video footage in your timeline. Whatever's in the timeline at the end of your edit is what makes your movie, so start adding clips from your project files to the timeline at the bottom of the Openshot window.
![Openshot interface to add clips to the timeline][7]
Adding clips to the timeline
The _rough assembly_, as the initial edit is commonly called, is a sublimely simple and quick process in Openshot. You can throw clips into the timeline hastily, either straight from the **Project files** panel (right-click and select **Add to timeline** or just press **Ctrl+W**), or by dragging and dropping.
Once you have a bunch of clips in the timeline, in more or less the correct order, you can take another pass to refine how much of each clip plays with each cut. You can cut video clips in the timeline short with the scissors (or _Razor tool_ in Openshot's terminology, but the icon is a scissor), or you can move the order of clips, intercut from shot to shot, and so on. For quick cross dissolves, just overlay the beginning of a clip over the end of another. Openshot takes care of the transition.
Should you find that some clips have stray background sound that you don't need, you can separate the audio from the video. To extract audio from a clip in the timeline, right-click on it and select **Separate audio**. The clip's audio appears as a new clip on the track below its parent.
### Exporting video from Openshot
Fast-forward several hours, days, or months, and you're done with your video edit. You're ready to release it to the world, or your family or friends, or to whomever your audience may be. It's time to export.
To export a video, click the **File** menu and select **Export video**. This selection brings up an **Export Video** window, with a **Simple** and **Advanced** tab.
The **Simple** tab provides a few formats for you to choose from: Bluray, DVD, Device, and Web. These are common targets for videos, and general presets are assigned by default to each.
The **Advanced** tab offers profiles based on output video size and quality, with overrides available for both video and audio. You can manually enter the video format, codec, and bitrate you want to use for the export. I prefer to export to an uncompressed format and then use ffmpeg manually, so that I can do multipass renders and also target several different formats as a batch process. However, this is entirely optional, but this attention to the needs of many different use cases is part of what makes Openshot great.
### Editing video on Linux with Openshot
This short article hardly does Openshot justice. It has many more features and conveniences, but you'll discover those as you use it.
If you're a content creator with a deadline, you'll appreciate the speed of Openshot's workflow. If you're a moviemaker with no budget, you'll appreciate Openshot's low, low price of $0. If you're a proud parent struggling to extract just the parts of the school play featuring your very own rising star, you'll appreciate how easy it is to use Openshot. Cutting to the chase: Editing videos on the Linux desktop is easy, fun, and fast.
A review of 6 free and open source (FOSS) video editing tools. Who came out the winner? Find out in...
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/2/linux-python-video
作者:[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/video_editing_folder_music_wave_play.png?itok=-J9rs-My (video editing dashboard)
[2]: https://opensource.com/article/18/4/new-state-video-editing-linux
[3]: http://openshot.org
[4]: https://opensource.com/article/17/6/ffmpeg-convert-media-file-formats
[5]: https://opensource.com/sites/default/files/openshot-import-2021.png
[6]: https://opensource.com/sites/default/files/openshot-tag-2021.png
[7]: https://opensource.com/sites/default/files/openshot-timeline-2021.png

View File

@@ -1,183 +0,0 @@
[#]: subject: "5 tips for choosing an Ansible collection that's right for you"
[#]: via: "https://opensource.com/article/21/3/ansible-collections"
[#]: author: "Tadej Borovšak https://opensource.com/users/tadeboro"
[#]: collector: "lkxed"
[#]: translator: " "
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
5 tips for choosing an Ansible collection that's right for you
======
Try these strategies to find and vet collections of Ansible plugins and modules before you install them.
![Women in computing and open source][1]
Image by: Ray Smith
In August 2020, Ansible issued its first release since the developers split the core functionality from the vast majority of its modules and plugins. A few [basic Ansible modules][2] remain part of core Ansible—modules for templating configuration files, managing services, and installing packages. All the other modules and plugins found their homes in dedicated [Ansible collections][3].
This article offers a quick look at Ansible collections in general and—especially—how to recognize high-quality ones.
### What are Ansible collections?
At its core, an Ansible collection is a collection (pun intended) of related modules and plugins that you can manage independently from Ansible's core engine. For example, the [Sensu Go Ansible collection][4] contains Ansible content for managing all aspects of Sensu Go. It includes Ansible roles for installing Sensu Go components and modules for creating, updating, and deleting monitoring resources. Another example is the [Sops Ansible collection][5] that integrates [Mozilla's Secret Operations editor][6] with Ansible.
With the introduction of Ansible collections, [Ansible Galaxy][7] became the central hub for all Ansible content. Authors publish their Ansible collections there, and Ansible users use Ansible Galaxy's search function to find Ansible content they need.
Ansible comes bundled with the `ansible-galaxy` tool for installing collections. Once you know what Ansible collection you want to install, things are relatively straightforward: Run the installation command listed on the Ansible Galaxy page. Ansible takes care of downloading and installing it. For example:
```
$ ansible-galaxy collection install sensu.sensu_go
Process install dependency map
Starting collection install process
Installing 'sensu.sensu_go:1.7.1' to
  '/home/user/.ansible/collections/ansible_collections/sensu/sensu_go'
```
But finding the Ansible collection you need and vetting its contents are the harder parts.
### How to select an Ansible collection
In the old times of monolithic Ansible, using third-party Ansible modules and plugins was not for the faint of heart. As a result, most users used whatever came bundled with their version of Ansible.
The ability to install Ansible collections offered a lot more control over the content you use in your Ansible playbooks. You can install the core Ansible engine and then equip it with the modules, plugins, and roles you need. But, as always, with great power comes great responsibility.
Now users are solely responsible for the quality of content they use to build Ansible playbooks. But how can you separate high-quality content from the rest? Here are five things to check when evaluating an Ansible collection.
#### 1. Documentation
Once you find a potential candidate on Ansible Galaxy, check its documentation first. In an ideal world, each Ansible collection would have a dedicated documentation site. For example, the [Sensu Go][8] and [F5 Networks][9] Ansible collections have them. Most other Ansible collections come only with a README file, but this will change for the better once the documentation tools mature.
The Ansible collection's documentation should contain at least a quickstart tutorial with installation instructions. This part of the documentation aims to have users up and running in a matter of minutes. For example, the Sensu Go Ansible collection has a [dedicated quickstart guide][10], while the Sops Ansible collection includes this information in [its README][11] file.
Another essential part of the documentation is a detailed module, plugin, and role reference guide. Collection authors do not always publish those guides on the internet, but they should always be accessible with the `ansible-doc` tool.
```
$ ansible-doc community.sops.sops_encrypt
> SOPS_ENCRYPT    (/home/tadej/.ansible/collections/ansible>
        Allows to encrypt binary data (Base64 encoded), text
        data, JSON or YAML data with sops.
  * This module is maintained by The Ansible Community
OPTIONS (= is mandatory):
- attributes
        The attributes the resulting file or directory should
        have.
        To get supported flags look at the man page for
        `chattr' on the target system.
        This string should contain the attributes in the same
        order as the one displayed by `lsattr'.
        The `=' operator is assumed as default, otherwise `+'
        or `-' operators need to be included in the string.
        (Aliases: attr)[Default: (null)]
        type: str
        version_added: 2.3
...
```
#### 2. Playbook readability
An Ansible playbook should serve as a human-readable description of the desired state. To achieve that, modules from the Ansible collection under evaluation should have a consistent user interface and descriptive parameter names.
For example, if Ansible modules interact with a web service, authentication parameters should be separated from the rest. And all modules should use the same authentication parameters if possible.
```
- name: Create a check that runs every 30 seconds
  sensu.sensu_go.check:
    auth: &auth
      url: https://my.sensu.host:8080
      user: demo
      password: demo-pass
    name: check
    command: check-cpu.sh -w 75 -c 90
    interval: 30
    publish: true
- name: Create a filter
  sensu.sensu_go.filter:
    # Reuse the authentication data from before
    auth: *auth
    name: filter
    action: deny
    expressions:
      - event.check.interval == 10
      - event.check.occurrences == 1
```
#### 3. Basic functionality
Before you start using third-party Ansible content in production, always check each Ansible module's basic functionality.
Probably the most critical property to look for is the result. Ansible modules and roles that enforce a state are much easier to use than their action-executing counterparts. This is because you can update your Ansible playbook and rerun it without risking a significant breakage.
```
- name: Command module executes an action -> fails on re-run
  ansible.builtin.command: useradd demo
- name: User module enforces a state -> safe to re-run
  ansible.builtin.user:
    name: demo
```
You should also expect support for [check mode][12], which simulates the change without making it. If you combine check mode with state enforcement, you get a configuration drift detector for free.
```
$ ansible-playbook --check playbook.yaml
PLAY [host] ************************************************
TASK [Create user] *****************************************
ok: [host]
...
PLAY RECAP *************************************************
host        : ok=5    changed=2    unreachable=0    failed=0
                      skipped=3        rescued=0   ignored=0
```
#### 4. Implementation robustness
A robustness check is a bit harder to perform if you've never developed an Ansible module or role before. Checking the continuous integration/continuous delivery (CI/CD) configuration files should give you a general idea of what is tested. Finding `ansible-test` and `molecule` commands in the test suite is an excellent sign.
#### 5. Maintenance
During your evaluation, you should also take a look at the issue tracker and development activity. Finding old issues with no response from maintainers is one sign of a poorly maintained Ansible collection.
Judging the health of a collection by the development activity is a bit trickier. No commits in the last year are a sure sign of an unmaintained Ansible collection because the Ansible ecosystem is developing rapidly. Seeing a few commits per month is usually a sign of a mature project that receives timely updates.
### Time well-spent
Evaluating Ansible collections is not an entirely trivial task. Hopefully, these tips will make your selection process somewhat more manageable. It does take time and effort to find the appropriate content for your use case. But with automation becoming an integral part of almost everything, all this effort is well-spent and will pay dividends in the future.
If you are thinking about creating your own Ansible Collection, you can download a [free eBook from Steampunk][13] packed full of advice on building and maintaining high-quality Ansible integrations.
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/3/ansible-collections
作者:[Tadej Borovšak][a]
选题:[lkxed][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/tadeboro
[b]: https://github.com/lkxed
[1]: https://opensource.com/sites/default/files/lead-images/OSDC_women_computing_3.png
[2]: https://docs.ansible.com/ansible/latest/collections/ansible/builtin/
[3]: https://docs.ansible.com/ansible/latest/collections/index.html#list-of-collections
[4]: https://galaxy.ansible.com/sensu/sensu_go
[5]: https://galaxy.ansible.com/community/sops
[6]: https://github.com/mozilla/sops
[7]: https://galaxy.ansible.com/
[8]: https://sensu.github.io/sensu-go-ansible/
[9]: https://clouddocs.f5.com/products/orchestration/ansible/devel/
[10]: https://sensu.github.io/sensu-go-ansible/quickstart-sensu-go-6.html
[11]: https://github.com/ansible-collections/community.sops#using-this-collection
[12]: https://docs.ansible.com/ansible/latest/user_guide/playbooks_checkmode.html#using-check-mode
[13]: https://steampunk.si/pdf/Importance_of_High_quality_Ansible_Collections_XLAB_Steampunk_ebook.pdf

View File

@@ -1,223 +0,0 @@
[#]: subject: "Build a home thermostat with a Raspberry Pi"
[#]: via: "https://opensource.com/article/21/3/thermostat-raspberry-pi"
[#]: author: "Joe Truncale https://opensource.com/users/jtruncale"
[#]: collector: "lkxed"
[#]: translator: " "
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
Build a home thermostat with a Raspberry Pi
======
The ThermOS project is an answer to the many downsides of off-the-shelf smart thermostats.
![Orange home vintage thermostat][1]
Image by: Photo by [Moja Msanii][2] on [Unsplash][3]
My wife and I moved into a new home in October 2020. As soon as it started getting cold, we realized some shortcomings of the home's older heating system (including one heating zone that was *always* on). We had Nest thermostats in our previous home, and the current setup was not nearly as convenient. There are multiple thermostats in our house, and some had programmed heating schedules, others had different schedules, some had none at all.
![Old thermostats][4]
The home's previous owner left notes explaining how some of the thermostats worked. (Joseph Truncale, CC BY-SA 4.0)
It was time for a change, but the house has some constraints:
* It was built in the late 1960s with a renovation during the '90s.
* The heat is hydronic (hot water baseboard).
* It has six thermostats for the six heating zones.
* There are only two wires that go to each thermostat for heat (red and white).
![Furnace valves][5]
### To buy or to build?
I wanted "smart" thermostat control for all of the heat zones (schedules, automations, home/away, etc.). I had several options if I wanted to buy something off the shelf, but all of them have drawbacks:
**Option 1: A Nest or Ecobee**
* It's expensive: No smart thermostat can handle multiple zones, so I would need one for each zone (~$200*6 = $1,200).
* It's difficult: I would have to rerun the thermostat wire to get the infamous [C wire][6], which enables continuous power to the thermostat. The wires are 20 to 100 feet each, in-wall, and might be stapled to the studs.
**Option 2: A battery-powered thermostat** such as the [Sensi WiFi thermostat][7]
* The batteries last only a month or two.
* It's not HomeKit-compatible in battery-only mode.
**Option 3: A commercial-off-the-shelf thermostat**, but only one exists (kind of): [Honeywell's TrueZONE][8]
* It's old and poorly supported (it was released in 2008).
* It's expensive—more than $300 for just the controller, and you need a [RedLINK gateway][9] for a shoddy app to work.
And the winner is…
**Option 4: Build my own!**
I decided to build my own multizone smart thermostat, which I named [ThermOS][10].
* It's centralized at the furnace (you need one device, not six).
* It uses the existing in-wall thermostat wires.
* It's HomeKit compatible, complete with automation, scheduling, home/away, etc.
* Anddddd it's… fun? Yeah, fun… I think.
### The ThermOS hardware
I knew that I wanted to use a Raspberry Pi. Since they've gotten so inexpensive, I decided to use a Raspberry Pi 4 Model B 2GB. I'm sure I could get by with a Raspberry Pi Zero W, but that will be for a future revision.
Here's a full list of the parts I used:
| Name | Quantity | Price |
| :- | :- | :- |
| Raspberry Pi 4 Model B 2GB | 1 | $29.99 |
| Raspberry Pi 4 official 15W power supply | 1 | $6.99 |
| Inland 400 tie-point breadboard | 1 | $2.99 |
| Inland 8 channel 5V relay module for Arduino | 1 | $8.99 |
| Inland DuPont jumper wire 20cm (3 pack) | 1 | $4.99 |
| DS18B20 temperature sensor (genuine) from Mouser.com | 6 | $6.00 |
| 3-pin screw terminal blocks (40 pack) | 1 | $7.99 |
| RPi GPIO terminal block breakout board module for Raspberry Pi | 1 | $17.99 |
| Alligator clip test leads (10 pack) | 1 | $5.89 |
| Southwire 18/2 thermostat wire (50ft) | 1 | $10.89 |
| Shrinkwrap | 1 | $4.99 |
| Solderable breadboard (5 pack) | 1 | $11.99 |
| PCB mounting brackets (50 pack) | 1 | $7.99 |
| Plastic housing/enclosure | 1 | $27.92 |
I began drawing out the hardware diagram on [draw.io][11] and realized I lacked some crucial knowledge about the furnace. I opened the side panel and found the step-down transformer that takes the 120V electrical line and makes it 24V for the heating system. If your heating system is anything like mine, you'll see a lot of jumper wires between the Taco zone valves. Terminal 3 on the Taco is jumped across all of my zone valves. This is because it doesn't matter how many valves are on/open—it just controls the circulator pump. If any combination of one to five valves is open, it should be on; if no valves are open, it should be off… simple!
![Furnace wiring architecture][12]
At its core, a thermostat is just a type of switch. Once the thermistor (temp sensor) inside the thermostat detects a lower temperature, the switch closes and completes the 24V circuit. Instead of having a thermostat in every room, this project keeps all of them right next to the furnace so that all six-zone valves can be controlled by a relay module using six of the eight relays. The Raspberry Pi acts as the brains of the thermostat and controls each relay independently.
![Manually setting relays using Raspberry Pi and Python][13]
The next problem was how to get temperature readings from each room. I could have a wireless temperature sensor in each room running on an Arduino or Raspberry Pi, but that can get expensive and complicated. Instead, I wanted to reuse the existing thermostat wire in the walls but purely for temperature sensors.
The "1-wire" [DS18B20][14] temperature sensor appeared to fit the bill:
* It has an accuracy of +/- 0.5°C or 0.9°F.
* It uses the "1-wire" protocol for data.
* Most importantly, the DS18B20 can use "[parasitic power][15]" mode where it needs just two wires for power and data. Just a heads up… almost all of the DS18B20s out there are [counterfeit][16]. I purchased a few (hoping they were genuine), but they wouldn't work when I tried to use parasitic power. I then bought real ones from [Mouser.com][17], and they worked like a charm!
![Temperature sensors][18]
Starting with a breadboard and all the components locally, I started writing code to interact with all of it. Once I proved out the concept, I added the existing in-wall thermostat wire into the mix. I got consistent readings with that setup, so I set out to make them a bit more polished. With help from my [dad][19], the self-proclaimed "just good enough" solderer, we soldered leads to the three-pin screw terminals (to avoid overheating the sensor) and then attached the sensor into the terminals. Now the sensors can be attached with wire nuts to the existing in-wall wiring.
![Attaching temperature sensors][20]
I'm still in the process of "prettifying" my temperature sensor wall mounts, but I've gone through a few 3D printing revisions, and I think I'm almost there.
![Wall mounts][21]
### The ThermOS software
As usual, writing the logic wasn't the hard part. However, deciding on the application architecture and framework was a confusing, multi-day process. I started out evaluating open source projects like [PiHome][22], but it relied on specific hardware *and* was written in PHP. I'm a Python fan and decided to start from scratch and write my own REST API.
Since HomeKit integration was so important, I figured I would eventually write a [HomeBridge][23] plugin to integrate it. I didn't realize that there was an entire Python HomeKit framework called [HAP-Python][24] that implements the accessory protocol. It helped me get a proof of concept running and controlled through my iPhone's Home app within 30 minutes.
![ThermOS HomeKit integration][25]
![ThermOS software architecture][26]
The rest of the "temp" logic is relatively straightforward, but I do want to highlight a piece that I initially missed. My code was running for a few days, and I was working on the hardware, when I noticed that my relays were turning on and off every few seconds. This "short-cycling" isn't necessarily harmful, but it certainly isn't efficient. To avoid that, I added some thresholding to make sure the heat toggles only when it's +/- 0.5C°.
Here is the threshold logic (you can see the [rubber-duck debugging][27] in the comments):
```
# check that we want heat
if self.target_state.value == 1:
    # if heat relay is already on, check if above threshold
    # if above, turn off .. if still below keep on
    if GPIO.input(self.relay_pin):
        if self.current_temp.value - self.target_temp.value >= 0.5:
            status = 'HEAT ON - TEMP IS ABOVE TOP THRESHOLD, TURNING OFF'
            GPIO.output(self.relay_pin, GPIO.LOW)
        else:
            status = 'HEAT ON - TEMP IS BELOW TOP THRESHOLD, KEEPING ON'
            GPIO.output(self.relay_pin, GPIO.HIGH)
    # if heat relay is not already on, check if below threshold
    elif not GPIO.input(self.relay_pin):
        if self.current_temp.value - self.target_temp.value <= -0.5:
            status = 'HEAT OFF - TEMP IS BELOW BOTTOM THRESHOLD, TURNING ON'
            GPIO.output(self.relay_pin, GPIO.HIGH)
        else:
          status = 'HEAT OFF - KEEPING OFF'
```
![Thresholding][28]
And I achieved my ultimate goal—to be able to control all of it from my phone.
![ThermOS as a HomeKit Hub][29]
### Putting my ThermOS in a lunchbox
My proof of concept was pretty messy.
![Initial ThermOS setup][30]
With the software and general hardware design in place, I started figuring out how to package all of the components in a more permanent and polished form. One of my main concerns for a permanent installation was to use a breadboard with DuPont jumper wires. I ordered some [solderable breadboards][31] and a [screw terminal breakout board][32] (thanks [@arduima][33] for the Raspberry Pi GPIO pins).
Here's what the solderable breadboard with mounts and enclosure looked like in progress.
![ThermOS hardware][34]
And here it is, mounted in the boiler room.
![ThermOS mounted][35]
Now I just need to organize and label the wires, and then I can start swapping the remainder of the thermostats over to ThermOS. And I'll be on to my next project: ThermOS for my central air conditioning.
Image by: (Joseph Truncale, CC BY-SA 4.0)
*This originally appeared on [Medium][36] and is republished with permission.*
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/3/thermostat-raspberry-pi
作者:[Joe Truncale][a]
选题:[lkxed][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/jtruncale
[b]: https://github.com/lkxed
[1]: https://opensource.com/sites/default/files/lead-images/home-thermostat.jpg
[2]: https://unsplash.com/@mojamsanii?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText
[3]: https://unsplash.com/s/photos/thermostat?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText
[4]: https://opensource.com/sites/default/files/uploads/oldthermostats.jpeg
[5]: https://opensource.com/sites/default/files/uploads/furnacevalves.jpeg
[6]: https://smartthermostatguide.com/thermostat-c-wire-explained/
[7]: https://www.amazon.com/Emerson-Thermostat-Version-Energy-Certified/dp/B01NB1OB0I
[8]: https://www.honeywellhome.com/us/en/products/air/forced-air-zone-panels/truezone-hz432-panel-hz432-u/
[9]: https://www.amazon.com/Honeywell-Redlink-Enabled-Internet-THM6000R7001/dp/B0783HK9ZZ
[10]: https://github.com/truncj/thermos
[11]: http://draw.io/
[12]: https://opensource.com/sites/default/files/uploads/furnacewiring.png
[13]: https://opensource.com/sites/default/files/uploads/settingrelays.gif
[14]: https://datasheets.maximintegrated.com/en/ds/DS18B20.pdf
[15]: https://learn.openenergymonitor.org/electricity-monitoring/temperature/DS18B20-temperature-sensing
[16]: https://github.com/cpetrich/counterfeit_DS18B20
[17]: https://www.mouser.com/
[18]: https://opensource.com/sites/default/files/uploads/tempsensors.png
[19]: https://twitter.com/jofredrick
[20]: https://opensource.com/sites/default/files/uploads/attachingsensors.jpeg
[21]: https://opensource.com/sites/default/files/uploads/wallmount.jpeg
[22]: https://github.com/pihome-shc/pihome
[23]: https://github.com/homebridge/homebridge
[24]: https://github.com/ikalchev/HAP-python
[25]: https://opensource.com/sites/default/files/uploads/iphoneintegration.gif
[26]: https://opensource.com/sites/default/files/uploads/thermosarchitecture.png
[27]: https://en.wikipedia.org/wiki/Rubber_duck_debugging
[28]: https://opensource.com/sites/default/files/uploads/thresholding.png
[29]: https://opensource.com/sites/default/files/uploads/thermoshomekit.png
[30]: https://opensource.com/sites/default/files/uploads/unpackaged.jpeg
[31]: https://www.amazon.com/gp/product/B07ZV8FWM4/r
[32]: https://www.amazon.com/gp/product/B084C69VSQ/
[33]: https://twitter.com/dimitri_koshkin
[34]: https://opensource.com/sites/default/files/uploads/breadboard.png
[35]: https://opensource.com/sites/default/files/uploads/mounted.png
[36]: https://joetruncale.medium.com/thermos-d089e1c4974b

View File

@@ -1,382 +0,0 @@
[#]: subject: "Learn Java by building a classic arcade game"
[#]: via: "https://opensource.com/article/21/3/java-object-orientation"
[#]: author: "Vaneska Sousa https://opensource.com/users/vaneska"
[#]: collector: "lkxed"
[#]: translator: " "
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
Learn Java by building a classic arcade game
======
Practice how to structure a project and write Java code while having fun building a fun game.
![Learning and studying technology is the key to success][1]
Image by: [WOCinTech Chat][2], [CC BY 2.0][3]
As a second-semester student in systems and digital media at the Federal University of Ceará in Brazil, I was given the assignment to remake the classic Atari 2600 [Breakout game][4] from 1978. I am still in my infancy in learning software development, and this was a challenging experience. It was also a gainful one because I learned a lot, especially about applying object-oriented concepts.
![Breakout game][5]
I'll explain how I accomplished this challenge, and if you follow the step-by-step instructions, at the end of this article, you will have the first pieces of your own classic Breakout game.
### Choosing Java and TotalCross
Several of my courses use [Processing][6], a software engine that uses [Java][7]. Java is a great language for learning programming concepts, in part because it's a strongly typed language.
Despite being free to choose any language or framework for my Breakout project, I chose to continue in Java to apply what I've learned in my coursework. I also wanted to use a framework so that I did not need to do everything from scratch. I considered using Godot, but that would mean I would hardly need to program at all.
Instead, I chose [TotalCross][8]. It is an open source software development kit (SDK) and framework with a simple game engine that generates code for [Linux Arm][9] devices (like the Raspberry Pi) and smartphones. Also, because I work for TotalCross, I have access to developers with much more experience than I have and know the platform very well. It seemed to be the safest way and, despite some strife, I don't regret it one bit. It was very cool to develop the whole project and see it running on the phone and the [Raspberry Pi][10].
![Breakout remake][11]
### Define the project mechanics and structure
When starting to develop any application, and especially a game, you need to consider the main features or mechanics that will be implemented. I watched the original Breakout gameplay a few times and played some versions on the internet. Then I defined the game mechanics and project structure based on what I learned.
#### Game mechanics
1. The platform moves left or right, according to the user's command. When it reaches an end, it hits the "wall" (edge).
2. When the ball hits the platform, it returns in the opposite direction it came from.
3. Each time the ball hits a "brick" (blue, green, yellow, orange, or red), the brick disappears.
4. When all the bricks in level 01 have been destroyed, new ones appear (in the same position as the previous one), and the ball's speed increases.
5. When all the bricks in level 02 have been destroyed, the game continues without obstacles on the screen.
6. The game ends when the ball falls.
#### Project structure
* RunBreakoutApplication.java is the class responsible for calling the class that inherits the `GameEngine` and runs the simulator.
* Breakout.java is the main class, which inherits from the `GameEngine` class and "assembles" the game, where it will call objects, define positions, etc.
* The `sprites` package is where all the classes responsible for the sprites (e.g., the image and behavior of the blocks, platform, and ball) go.
* The `util` packages contain classes used to facilitate project maintenance, such as constants, image initialization, and colors.
### Get hands-on with code
First, install the [TotalCross plugin from VSCode][12]. If you are using another [integrated development environment][13] (IDE), check TotalCross's documentation for installation instructions.
If you're using the plugin, just press `Ctrl` +`P`, type `totalcross`, and click `Create new project`. Fill in the requested information:
* Folder name: gameTC
* ArtifactId: com.totalcross
* Project name: Breakout
* TotalCross version: 6.1.1 (or the most recent one)
* Build platforms: -Android and -Linux_arm (select the platforms you want)
When filling in the fields above and generating the project, if you are in the `RunBreakoutApplication.java` class, right-clicking on it and clicking "run" will open the simulator, and "Hello World!" will appear on your screen if you have created your Java project with TotalCross properly.
![HelloWorld project structure][14]
If you have a problem, check the [documentation][15] or ask the [TotalCross community][16] on Telegram for help.
After the project is configured, the next step is to add the project's images in `Resources` > `Sprites`. Create two packages named `util` and `sprites` to work on later.
The structure of your project will be:
![Project structure][17]
### Go behind the scenes
To make it easier to maintain the code and change the images to the colors you want to use, it's a good practice to [centralize everything by creating classes][18]. Place all of the classes for this function inside the `util` package.
#### Constants.java
First, create the `constants.java` class, which is where placement patterns (such as the edge between the screen and where the platform starts), speed, number of blocks, etc., reside. This is good for playing, changing numbers, and understanding where things change and why. It is a great exercise for those just starting with Java.
```
package com.totacross.util;
import totalcross.sys.Settings;
import totalcross.ui.Control;
import totalcross.util.UnitsConverter;
public class Constants {
    //Position
    public static final int BOTTOM_EDGE = UnitsConverter.toPixels(430 + Control.DP);
    public static final int DP_23 = UnitsConverter.toPixels(23 + Control.DP);
    public static final int DP_50 = UnitsConverter.toPixels(50 + Control.DP);
    public static final int DP_100 = UnitsConverter.toPixels(100 + Control.DP);
    //Sprites
    public static final int EDGE_RACKET = UnitsConverter.toPixels(20 + Control.DP);
    public static final int WIDTH_BALL =  UnitsConverter.toPixels(15 + Control.DP);
    public static final int HEIGHT_BALL =  UnitsConverter.toPixels(15 + Control.DP);
    //Bricks
    public static final int NUM_BRICKS = 10;
    public static final int WIDTH_BRICKS = Settings.screenWidth / NUM_BRICKS;
    public static final int HEIGHT_BRICKS = Settings.screenHeight / 32;
    //Brick Points
    public static final int BLUE_POINT = 1;
    public static final int GREEN_POINT = 2;
    public static final int YELLOW_POINT = 3;
    public static final int DARK_ORANGE_POINT = 4;
    public static final int ORANGE_POINT = 5;
    public static final int RED_POINT = 6;
}
```
If you want to know more about the pixel density (DP) unit, I recommend reading the [Material Design description][19].
#### Colors.java
As the name suggests, this class is where you define the colors used in the game. I recommend naming things according to the color's purpose, such as background, font color, etc. This will make it easier to update your project's color palette in a single class.
```
package com.totacross.util;
public class Colors {
    public static int PRIMARY = 0x161616;
    public static int P_FONT = 0xFFFFFF;
    public static int SECONDARY = 0xE63936;
    public static int SECONDARY_DARK = 0xCE3737;
}
```
#### Images.java
The `images.java` class is undoubtedly the most frequently used.
```
package com.totacross.util;
import static com.totacross.util.Constants.*;
import totalcross.ui.dialog.MessageBox;
import totalcross.ui.image.Image;
public class Images {
    public static Image paddle, ball;
    public static Image red, orange, dark_orange, yellow, green, blue;
    public static void loadImages() {
        try {
            // general
            paddle = new Image("sprites/paddle.png");
            ball = new Image("sprites/ball.png").getScaledInstance(WIDTH_BALL, HEIGHT_BALL);
            // Bricks
            red = new Image("sprites/red_brick.png").getScaledInstance(WIDTH_BRICKS, HEIGHT_BRICKS);
            orange = new Image("sprites/orange_brick.png").getScaledInstance(WIDTH_BRICKS, HEIGHT_BRICKS);
            dark_orange = new Image("sprites/orange2_brick.png").getScaledInstance(WIDTH_BRICKS, HEIGHT_BRICKS);
            yellow = new Image("sprites/yellow_brick.png").getScaledInstance(WIDTH_BRICKS, HEIGHT_BRICKS);
            green = new Image("sprites/green_brick.png").getScaledInstance(WIDTH_BRICKS, HEIGHT_BRICKS);
            blue = new Image("sprites/blue_brick.png").getScaledInstance(WIDTH_BRICKS, HEIGHT_BRICKS);
        } catch (Exception e) {
            MessageBox.showException(e, true);
        }
    }
}
```
The `getScaledInstance()` method will manipulate the image to match the values passed through the constant. Try to change these values and observe the impact on the game.
#### Recap
At this point, your project should look like this:
![Project structure][20]
### Create your first sprite
Now that the project is structured properly, you're ready to create your first class in the sprite package: `paddle.java`, which is the platform—the user's object of interaction.
#### Paddle.java
The `paddle.java` class must inherit from `sprite`, which is the class responsible for objects in games. This is a fundamental concept in game engine development, so when inheriting from sprites, the TotalCross framework will already be concerned with delimiting movement within the screen, detecting collisions between sprites, and other important functions. You can check all the details in [Javadoc][21].
In Breakout, the paddle moves on the X-axis at a speed determined by the user's command (by touch screen or mouse movement). The `paddle.java` class is responsible for defining this movement and the sprite's image (the "face"):
```
package com.totacross.sprites;
import com.totacross.util.Images;
import totalcross.game.Sprite;
import totalcross.ui.image.ImageException;
public class Paddle extends Sprite {
  private static final int SPEED = 4;
  public Paddle() throws IllegalArgumentException, IllegalStateException, ImageException {
    super(Images.paddle, -1, true, null);
  }
  //Move the platform according the speed and the direction
  public final void move(boolean left, int speed) {
    if (left) {
      centerX -= SPEED;
    } else {
      centerX += SPEED;
    }
    setPos(centerX, centerY, true);
  }
}
```
You indicate the image (`Images.paddle` ) within the constructor, and the `move` method (a TotalCross feature) receives the speed defined at the beginning of the class. Experiment with other values and observe what happens with the movement.
When the paddle is moving to the left, the center of the paddle at any moment is defined as itself minus the speed, and when it's moving to the right, it's itself plus the speed. Ultimately, you define the position of the sprite on the screen.
Now your sprite is ready, so you need to add it on the screen and include the user's movement to call the `move` method and create movement. Do this in your main class, `Breakout.java`.
#### Add onscreen and user interaction
When building your game engine, you need to focus on some standard points. For the sake of brevity, I'll add comments in the code.
Basically, you will delete the automatically generated `initUI()` method and, instead of inheriting from `MainWindow`, you will inherit it from `GameEngine`. A "red" will appear in the name of your class, so just click on the lamp or the suggestion symbol for your IDE and click `Add unimplemented methods`. This will automatically generate the `onGameInit()` method, which is responsible for the moment when the game starts, i.e., the moment the `breakout` class is called.
Inside the constructor, you must add the style type (`MaterialUI` ) and the refresh time on the screen (`70` ), and signal that the game has an interface (`gameHasUI = true;` ).
Last but not least, you have to start the game through `this.start()` on `onGameInit()` and focus on some other methods:
* onGameInit() is the first method called. In it, you must initialize the sprites and images (Images.loadImages), and tell the game that it can start.
* onGameStart()is called when the game starts. It sets the platform's initial position (in the center of the screen on the X-axis and below the center with a border on the Y-axis).
* onPaint() is where you say what will be drawn for each frame. First, it paints the background black (to not leave traces of the sprites), then it displays the sprites with `.show()`.
* The `onPenDrag` and `onPenDown` methods identify when the user `move`s the paddle (by dragging a finger on a touch screen or moving the mouse while pressing the left button). These methods change the paddle movement through the `setPos()` method, which triggers the move method in the `Paddle.java` class. Note that the last parameter of the `racket.setPos` method is `true` to precisely limit the paddle's movement within the screen so that it never disappears from the user's field of view.
```
package com.totacross;
import com.totacross.sprites.Paddle;
import com.totacross.util.Colors;
import com.totacross.util.Constants;
import com.totacross.util.Images;
import totalcross.game.GameEngine;
import totalcross.sys.Settings;
import totalcross.ui.MainWindow;
import totalcross.ui.dialog.MessageBox;
import totalcross.ui.event.PenEvent;
import totalcross.ui.gfx.Graphics;
public class Breakout extends GameEngine {
    private Paddle racket;
    public Breakout() {
        setUIStyle(Settings.MATERIAL_UI);
        gameName = "Breakout";
        gameVersion = 100;
        gameHasUI = true;
        gameRefreshPeriod = 70;
    }
    @Override
    public void onGameInit() {
        setBackColor(Colors.PRIMARY);
        Images.loadImages();
        try {
            racket = new Paddle();
        } catch (Exception e) {
            MessageBox.showException(e, true);
            MainWindow.exit(0);
        }
        this.start();
    }
    public void onGameStart() {
        racket.setPos(Settings.screenWidth / 2, (Settings.screenHeight - racket.height) - Constants.EDGE_RACKET, true);
    }
     //to draw the interface
     @Override
     public void onPaint(Graphics g) {
         super.onPaint(g);
         if (gameIsRunning) {
             g.backColor = Colors.PRIMARY;
             g.fillRect(0, 0, this.width, this.height);
             if (racket != null) {
                 racket.show();
             }
         }
     }
     //To make the paddle moving with the mouse/press moviment
     @Override
     public final void onPenDown(PenEvent evt) {
         if (gameIsRunning) {
             racket.setPos(evt.x, racket.centerY, true);
         }
     }
     @Override
     public final void onPenDrag(PenEvent evt) {
         if (gameIsRunning) {
             racket.setPos(evt.x, racket.centerY, true);
         }
     }
}
```
### Run the game
To run the game, just click `RunBreakoutApplication.java` with the right mouse button, then click `run` to see how it looks.
![Breakout game remake][22]
If you want to run it on a Raspberry Pi, change the parameters in the `RunBreakoutApplication.java` class to:
```
TotalCrossApplication.run(Breakout.class, "/scr", "848x480");
```
This sets the screen size to match the Raspberry Pi.
![Breakout on Raspberry Pi][23]
The first sprite and game mechanics are ready!
### Next steps
In the next article, I'll show how to add the ball sprite and make collisions. If you need help, call me in the [community group][24] on Telegram or post in the TotalCross [forum][25], where I'm available to help.
If you put this article into practice, share your experience in the comments. All feedback is important! If you wish, favorite [TotalCross on GitHub][26], as it improves the project's relevance on the platform.
Image by: (Vaneska Karen, CC BY-SA 4.0)
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/3/java-object-orientation
作者:[Vaneska Sousa][a]
选题:[lkxed][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/vaneska
[b]: https://github.com/lkxed
[1]: https://opensource.com/sites/default/files/lead-images/studying-books-java-couch-education.png
[2]: https://www.wocintechchat.com/
[3]: https://creativecommons.org/licenses/by/2.0/
[4]: https://www.youtube.com/watch?v=Cr6z3AyhRr8
[5]: https://opensource.com/sites/default/files/uploads/originalbreakout.gif
[6]: https://processing.org/
[7]: https://opensource.com/resources/java
[8]: https://opensource.com/article/20/7/totalcross-cross-platform-development
[9]: https://www.arm.linux.org.uk/docs/whatis.php
[10]: https://opensource.com/resources/raspberry-pi
[11]: https://opensource.com/sites/default/files/uploads/breakoutremake.gif
[12]: https://marketplace.visualstudio.com/items?itemName=totalcross.vscode-totalcross
[13]: https://www.redhat.com/en/topics/middleware/what-is-ide
[14]: https://opensource.com/sites/default/files/uploads/helloworld.png
[15]: https://learn.totalcross.com/
[16]: https://t.me/guiforembedded
[17]: https://opensource.com/sites/default/files/uploads/projectstructure.png
[18]: https://learn.totalcross.com/documentation/guides/app-architecture/colors-fonts-and-images
[19]: https://material.io/design/layout/pixel-density.html
[20]: https://opensource.com/sites/default/files/uploads/projectstructure2.png
[21]: https://en.wikipedia.org/wiki/Javadoc
[22]: https://opensource.com/sites/default/files/uploads/runbreakout.gif
[23]: https://opensource.com/sites/default/files/uploads/runbreakout2.gif
[24]: https://t.me/guiforembedded
[25]: http://forum.totalcross.com
[26]: https://github.com/totalcross/totalcross

View File

@@ -1,474 +0,0 @@
[#]: subject: "Host your website with dynamic content and a database on a Raspberry Pi"
[#]: via: "https://opensource.com/article/21/3/web-hosting-raspberry-pi"
[#]: author: "Marty Kalin https://opensource.com/users/mkalindepauledu"
[#]: collector: "lkxed"
[#]: translator: " "
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
Host your website with dynamic content and a database on a Raspberry Pi
======
You can use free software to support a web application on a very lightweight computer.
![Digital creative of a browser on the internet][1]
Raspberry Pi's single-board machines have set the mark for cheap, real-world computing. With its model 4, the Raspberry Pi can host web applications with a production-grade web server, a transactional database system, and dynamic content through scripting. This article explains the installation and configuration details with a full code example. Welcome to web applications hosted on a very lightweight computer.
### The snowfall application
Imagine a downhill ski area large enough to have microclimates, which can mean dramatically different snowfalls across the area. The area is divided into regions, each of which has devices that record snowfall in centimeters; the recorded information then guides decisions on snowmaking, grooming, and other maintenance operations. The devices communicate, say, every 20 minutes with a server that updates a database that supports reports. Nowadays, the server-side software for such an application can be free *and* production-grade.
This snowfall application uses the following technologies:
* A [Raspberry Pi 4][2] running Debian
* Nginx web server: The free version hosts over 400 million websites. This web server is easy to install, configure, and use.
* [SQLite relational database system][3], which is file-based: A database, which can hold many tables, is a file on the local system. SQLite is lightweight but also [ACID-compliant][4]; it is suited for low to moderate volume. SQLite is likely the most widely used database system in the world, and the source code for SQLite is in the public domain. The current version is 3. A more powerful (but still free) option is PostgreSQL.
* Python: The Python programming language can interact with databases such as SQLite and web servers such as Nginx. Python (version 3) comes with Linux and macOS systems.
Python includes a software driver for communicating with SQLite. There are options for connecting Python scripts with Nginx and other web servers. One option is [uWSGI][5] (Web Server Gateway Interface), which updates the ancient CGI (Common Gateway Interface) from the 1990s.
Several factors speak for uWSGI:
* uWSGI is flexible. It can be used as either a lightweight concurrent web server or the backend application server connected to a web server such as Nginx.
* Its setup is minimal.
* The snowfall application involves a low to moderate volume of hits on the web server and database system. In general, CGI technologies are not fast by modern standards, but CGI performs well enough for department-level web applications such as this one.
Various acronyms describe the uWSGI option. Here's a sketch of the three principal ones:
* WSGI is a Python specification for an interface between a web server on one side, and an application or an application framework (e.g., Django) on the other side. This specification defines an API whose implementation is left open.
* uWSGI implements the WSGI interface by providing an application server, which connects applications to a web server. A uWSGI application server's main job is to translate HTTP requests into a format that a web application can consume and, afterward, to format the application's response into an HTTP message.
* uwsgi is a binary protocol implemented by a uWSGI application server to communicate with a full-featured web server such as Nginx; it also includes utilities such as a lightweight web server. The Nginx web server "speaks" uwsgi out of the box.
For convenience, I will use "uwsgi" as shorthand for the binary protocol, the application server, and the very lightweight web server.
### Setting up the database
On a Debian-based system, you can install SQLite the usual way (with `%` representing the command-line prompt):
```
% sudo apt-get install sqlite3
```
This database system is a collection of C libraries and utilities, all of which come to about 500KB in size. There is no database server to start, stop, or otherwise maintain.
Once SQLite is installed, create a database at the command-line prompt:
```
% sqlite3 snowfall.db
```
If this succeeds, the command creates the file `snowfall.db` in the current working directory. The database name is arbitrary (e.g., no extension is required), and the command opens the SQLite client utility with `>sqlite` as the prompt:
```
Enter ".help" for usage hints.
sqlite>
```
Create the snowfall table in the snowfall database with the following command. The table name, like the database name, is arbitrary:
```
sqlite> CREATE TABLE snowfall (id INTEGER PRIMARY KEY AUTOINCREMENT,
                               region TEXT NOT NULL,
                               device TEXT NOT NULL,
                               amount DECIMAL NOT NULL,
                               tstamp DECIMAL NOT NULL);
```
SQLite commands are case-insensitive, but it is traditional to use uppercase for SQL terms and lowercase for user terms. Check that the table was created:
```
sqlite> .schema
```
The command echoes the `CREATE TABLE` statement.
The database is now ready for business, although the single-table snowfall is empty. You can add rows interactively to the table, but an empty table is fine for now.
### A first look at the overall architecture
Recall that uwsgi can be used in two ways: either as a lightweight web server or as an application server connected to a production-grade web server such as Nginx. The second use is the goal, but the first is suited for developing and testing the programmer's request-handling code. Here's the architecture with Nginx in play as the web server:
```
HTTP       uwsgi
client<---->Nginx<----->appServer<--->request-handling code<--->SQLite
```
The client could be a browser, a utility such as [curl][6], or a hand-crafted program fluent in HTTP. Communications between the client and Nginx occur through HTTP, but then uwsgi takes over as a binary-transport protocol between Nginx and the application server, which interacts with request-handling code such as `requestHandler.py` (described below). This architecture delivers a clean division of labor. Nginx alone manages the client, and only the request-handling code interacts with the database. In turn, the application server separates the web server from the programmer-written code, which has a high-level API to read and write HTTP messages delivered over uwsgi.
I'll examine these architectural pieces and cover the steps for installing, configuring, and using uwsgi and Nginx in the next sections.
### The snowfall application code
Below is the source code file `requestHandler.py` for the snowfall application. (It's also available on my [website][7].) Different functions within this code help clarify the software architecture that connects SQLite, Nginx, and uwsgi.
#### The request-handling program
```
import sqlite3
import cgi
PATH_2_DB = '/home/marty/wsgi/snowfall.db'
## Dispatches HTTP requests to the appropriate handler.
def application(env, start_line):
    if env['REQUEST_METHOD'] == 'POST':   ## add new DB record
        return handle_post(env, start_line)
    elif env['REQUEST_METHOD'] == 'GET':  ## create HTML-fragment report
        return handle_get(start_line)
    else:                                 ## no other option for now
        start_line('405 METHOD NOT ALLOWED', [('Content-Type', 'text/plain')])
        response_body = 'Only POST and GET verbs supported.'
        return [response_body.encode()]                            
def handle_post(env, start_line):    
    form = get_field_storage(env)  ## body of an HTTP POST request
   
    ## Extract fields from POST form.
    region = form.getvalue('region')
    device = form.getvalue('device')
    amount = form.getvalue('amount')
    tstamp = form.getvalue('tstamp')
    ## Missing info?
    if (region is not None and
        device is not None and
        amount is not None and
        tstamp is not None):
        add_record(region, device, amount, tstamp)
        response_body = "POST request handled.\n"
        start_line('201 OK', [('Content-Type', 'text/plain')])
    else:
        response_body = "Missing info in POST request.\n"
        start_line('400 Bad Request', [('Content-Type', 'text/plain')])
 
    return [response_body.encode()]
def handle_get(start_line):
    conn = sqlite3.connect(PATH_2_DB)        ## connect to DB
    cursor = conn.cursor()                   ## get a cursor
    cursor.execute("select * from snowfall")
    response_body = "<h3>Snowfall report</h3><ul>"
    rows = cursor.fetchall()
    for row in rows:
        response_body += "<li>" + str(row[0]) + '|'  ## primary key
        response_body += row[1] + '|'                ## region
        response_body += row[2] + '|'                ## device
        response_body += str(row[3]) + '|'           ## amount
        response_body += str(row[4]) + "</li>"       ## timestamp
    response_body += "</ul>"
    conn.commit()  ## commit
    conn.close()   ## cleanup
   
    start_line('200 OK', [('Content-Type', 'text/html')])
    return [response_body.encode()]
## Add a record from a device to the DB.
def add_record(reg, dev, amt, tstamp):
    conn = sqlite3.connect(PATH_2_DB)      ## connect to DB
    cursor = conn.cursor()                 ## get a cursor
    sql = "INSERT INTO snowfall(region,device,amount,tstamp) values (?,?,?,?)"
    cursor.execute(sql, (reg, dev, amt, tstamp)) ## execute INSERT
    conn.commit()  ## commit
    conn.close()   ## cleanup
def get_field_storage(env):
    input = env['wsgi.input']
    form = env.get('wsgi.post_form')
    if (form is not None and form[0] is input):
        return form[2]
    fs = cgi.FieldStorage(fp = input,
                          environ = env,
                          keep_blank_values = 1)
    return fs
```
A constant at the start of the source file defines the path to the database file:
```
PATH_2_DB = '/home/marty/wsgi/snowfall.db'
```
Make sure to update the path for your Raspberry Pi.
As noted earlier, uwsgi includes a lightweight web server that can host this request-handling application. To begin, install uwsgi with these two commands (`##` introduces my comments):
```
% sudo apt-get install build-essential python-dev ## C header files, etc.
% pip install uwsgi                               ## pip = Python package manager
```
Next, launch a bare-bones snowfall application using uwsgi as the web server:
```
% uwsgi --http 127.0.0.1:9999 --wsgi-file requestHandler.py
```
The flag `--http` runs uwsgi in web-server mode, with 9999 as the web server's listening port on localhost (127.0.0.1). By default, uwsgi dispatches HTTP requests to a programmer-defined function named `application`. For review, here's the full function from the top of the `requestHandler.py` code:
```
def application(env, start_line):
    if env['REQUEST_METHOD'] == 'POST':   ## add new DB record
        return handle_post(env, start_line)
    elif env['REQUEST_METHOD'] == 'GET':  ## create HTML-fragment report
        return handle_get(start_line)
    else:                                 ## no other option for now
        start_line('405 METHOD NOT ALLOWED', [('Content-Type', 'text/plain')])
        response_body = 'Only POST and GET verbs supported.'
        return [response_body.encode()]
```
The snowfall application accepts only two request types:
* A POST request, if up to snuff, creates a new entry in the snowfall table. The request should include the ski area region, the device in the region, the snowfall amount in centimeters, and a Unix-style timestamp. A POST request is dispatched to the `handle_post` function (which I'll clarify shortly).
* A GET request returns an HTML fragment (an unordered list) with the records currently in the snowfall table.
Requests with an HTTP verb other than POST and GET will generate an error message.
You can use a utility such as curl to generate HTTP requests for testing. Here are three sample POST requests to start populating the database:
```
% curl -X POST -d "region=R1&device=D9&amount=1.42&tstamp=1604722088.0158753" localhost:9999/
% curl -X POST -d "region=R7&device=D4&amount=2.11&tstamp=1604722296.8862638" localhost:9999/
% curl -X POST -d "region=R5&device=D1&amount=1.12&tstamp=1604942236.1013834" localhost:9999/
```
These commands add three records to the snowfall table. A subsequent GET request from curl or a browser displays an HTML fragment that lists the rows in the snowfall table. Here's the equivalent as non-HTML text:
```
Snowfall report
    1|R1|D9|1.42|1604722088.0158753
    2|R7|D4|2.11|1604722296.8862638
    3|R5|D1|1.12|1604942236.1013834
```
A professional report would convert the numeric timestamps into human-readable ones. But the emphasis, for now, is on the architectural components in the snowfall application, not on the user interface.
The uwsgi utility accepts various flags, which can be given either through a configuration file or in the launch command. For example, here's a richer launch of uwsgi as a web server:
```
% uwsgi --master --processes 2 --http 127.0.0.1:9999 --wsgi-file requestHandler.py
```
This version creates a master (supervisory) process and two worker processes, which can handle the HTTP requests concurrently.
In the snowfall application, the functions `handle_post` and `handle_get` process POST and GET requests, respectively. Here's the `handle_post` function in full:
```
def handle_post(env, start_line):    
    form = get_field_storage(env)  ## body of an HTTP POST request
   
    ## Extract fields from POST form.
    region = form.getvalue('region')
    device = form.getvalue('device')
    amount = form.getvalue('amount')
    tstamp = form.getvalue('tstamp')
    ## Missing info?
    if (region is not None and
        device is not None and
        amount is not None and
        tstamp is not None):
        add_record(region, device, amount, tstamp)
        response_body = "POST request handled.\n"
        start_line('201 OK', [('Content-Type', 'text/plain')])
    else:
        response_body = "Missing info in POST request.\n"
        start_line('400 Bad Request', [('Content-Type', 'text/plain')])
 
    return [response_body.encode()]
```
The two arguments to the `handle_post` function (`env` and `start_line` ) represent the system environment and a communications channel, respectively. The `start_line` channel sends the HTTP start line (in this case, either `400 Bad Request` or `201 OK` ) and any HTTP headers (in this case, just `Content-Type: text/plain` ) of an HTTP response.
The `handle_post` function tries to extract the relevant data from the HTTP POST request and, if it's successful, calls the function `add_record` to add another row to the snowfall table:
```
def add_record(reg, dev, amt, tstamp):
    conn = sqlite3.connect(PATH_2_DB)      ## connect to DB
    cursor = conn.cursor()                 ## get a cursor
    sql = "INSERT INTO snowfall(region,device,amount,tstamp) VALUES (?,?,?,?)"
    cursor.execute(sql, (reg, dev, amt, tstamp)) ## execute INSERT
    conn.commit()  ## commit
    conn.close()   ## cleanup
```
SQLite automatically wraps single SQL statements (such as `INSERT` above) in a transaction, which accounts for the call to `conn.commit()` in the code. SQLite also supports multi-statement transactions. After calling `add_record`, the `handle_post` function winds up its work by sending an HTTP response confirmation message to the requester.
The `handle_get` function also touches the database, but only to read the records in the snowfall table:
```
def handle_get(start_line):
    conn = sqlite3.connect(PATH_2_DB)        ## connect to DB
    cursor = conn.cursor()                   ## get a cursor
    cursor.execute("SELECT * FROM snowfall")
    response_body = "<h3>Snowfall report</h3><ul>"
    rows = cursor.fetchall()
    for row in rows:
        response_body += "<li>" + str(row[0]) + '|'  ## primary key
        response_body += row[1] + '|'                ## region
        response_body += row[2] + '|'                ## device
        response_body += str(row[3]) + '|'           ## amount
        response_body += str(row[4]) + "</li>"       ## timestamp
    response_body += "</ul>"
    conn.commit()  ## commit
    conn.close()   ## cleanup
   
    start_line('200 OK', [('Content-Type', 'text/html')])
    return [response_body.encode()]
```
A user-friendly version of the snowfall application would support additional (and fancier) reports, but even this version of `handle_get` underscores the clean interface between Python and SQLite. By the way, uwsgi expects a response body to be a list of bytes. In the `return` statement, the call to `response_body.encode()` inside the square brackets generates the byte list from the `response_body` string.
### Moving up to Nginx
The Nginx web server can be installed on a Debian-based system with one command:
```
% sudo apt-get install nginx
```
As a web server, Nginx provides the expected services, such as wire-level security, HTTPS, user authentication, load balancing, media streaming, response compression, file uploading, etc. The Nginx engine is high-performance and stable, and this server can support dynamic content through a variety of programming languages. Using uwsgi as a very lightweight web server is an attractive option but switching to Nginx is a move up to industrial-strength web hosting with high-volume capability. Nginx and uwsgi are both implemented in C.
With Nginx in play, uwsgi takes on a communication protocol's restricted roles and an application server; it no longer acts as an HTTP web server. Here's the revised architecture:
```
HTTP       uwsgi                  
requester<---->Nginx<----->app server<--->requestHandler.py
```
As noted earlier, Nginx includes uwsgi support and now acts as a reverse-proxy server that forwards designated HTTP requests to the uwsgi application server, which in turn interacts with the Python script `requestHandler.py`. Responses from the Python script move in the reverse direction so that Nginx sends the HTTP response back to the requesting client.
Two changes bring this new architecture to life. The first launches uwsgi as an application server:
```
% uwsgi --socket 127.0.0.1:8001 --wsgi-file requestHandler.py
```
Socket 8001 is the Nginx default for uwsgi communications. For robustness, you could use the full path to the Python script so that the command above does not have to be executed in the directory that houses the Python script. In a production environment, uwsgi would start and stop automatically; for now, however, the emphasis remains on how the architectural pieces fit together.
The second change involves Nginx configuration, which can be tricky on Debian-based systems. The main configuration file for Nginx is `/etc/nginx/nginx.conf`, but this file may have `include` directives for other files, in particular, files in one of three `/etc/nginx` subdirectories: `nginx.d`, `sites-available`, and `sites-enabled`. The `include` directives can be eliminated to simplify matters; in this case, the configuration occurs only in `nginx.conf`. I recommend the simple approach.
However the configuration is distributed, the key section for having Nginx talk to the uwsgi application server begins with `http` and has one or more `server` subsections, which in turn have `location` subsections. Here's an example from the Nginx documentation:
```
...
http {
    # Configuration specific to HTTP and affecting all virtual servers  
    ...
    server { # simple reverse-proxy
       listen       80;
       server_name  domain2.com www.domain2.com;
       access_log   logs/domain2.access.log  main;
       # serve static files
       location ~ ^/(images|javascript|js|css|flash|media|static)/  {
         root    /var/www/virtual/big.server.com/htdocs;
         expires 30d;
       }
       # pass requests for dynamic content to rails/turbogears/zope, et al
       location / {
         proxy_pass      http://127.0.0.1:8080;
       }
     }
     ...
}
```
The `location` subsections are the ones of interest. For the snowfall application, here's the added `location` entry with its two configuration lines:
```
...
server {
   listen 80 default_server;
   listen [::]:80 default_server;
   root /var/www/html;
   index index.html index.htm index.nginx-debian.html;
   server_name _;
   ### key addition for uwsgi communication
   location /snowfall {
      include uwsgi_params;       ## comes with Nginx
      uwsgi_pass 127.0.0.1:8001;  ## 8001 is the default for uwsgi
   }
   ...
}
...
```
To keep things simple for now, make `/snowfall` the only `location` in the configuration. With this configuration in place, Nginx listens on port 80 and dispatches HTTP requests ending with the `/snowfall` path to the uwsgi application server:
```
% curl -X POST -d "..." localhost/snowfall ## new POST
% curl -X GET localhost/snowfall           ## new GET
```
The port number 80 can be dropped from the request because 80 is the default server port for HTTP requests.
If the configured location were simply `/` instead of `/snowfall`, then any HTTP request with `/` at the start of the path would be dispatched to the uwsgi application server. Accordingly, the `/snowfall` path leaves room for other locations and, therefore, for further actions in response to HTTP requests.
Once you've changed the Nginx configuration with the added `location` subsection, you can start the web server:
```
% sudo systemctl start nginx
```
There are other commands similar to `stop` and `restart` Nginx. In a production environment, you could automate these actions so that Nginx starts on a system boot and stops on a system shutdown.
With uwsgi and Nginx both running, you can use a browser to test whether the architectural components cooperate as expected. For example, if you enter the URL `localhost/` in the browser's input window, then the Nginx welcome page should appear with (HTML) content similar to this:
```
Welcome to nginx!
...
Thank you for using nginx.
```
By contrast, the URL `localhost/snowfall` should display the rows currently in the snowfall table:
```
Snowfall report
    1|R1|D9|1.42|1604722088.0158753
    2|R7|D4|2.11|1604722296.8862638
    3|R5|D1|1.12|1604942236.1013834
```
### Wrapping up
The snowfall application shows how free software components—a high-powered web server, an ACID-compliant database system, and scripting for dynamic content—can support a realistic web application on a Raspberry Pi 4 platform. This lightweight machine lifts above its weight class, and Debian eases the lifting.
The software components in the web application work well together and require very little configuration. For higher volume hits against a relational database, recall that a free and feature-rich alternative to SQLite is PostgreSQL. If you're eager to play on the Raspberry Pi 4—in particular, to explore server-side web programming on this platform—then Nginx, SQLite or PostgreSQL, uwsgi, and Python are worth considering.
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/3/web-hosting-raspberry-pi
作者:[Marty Kalin][a]
选题:[lkxed][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/mkalindepauledu
[b]: https://github.com/lkxed
[1]: https://opensource.com/sites/default/files/lead-images/browser_web_internet_website.png
[2]: https://www.raspberrypi.org/products/raspberry-pi-4-model-b/
[3]: https://opensource.com/article/21/2/sqlite3-cheat-sheet
[4]: https://en.wikipedia.org/wiki/ACID
[5]: https://uwsgi-docs.readthedocs.io/en/latest/
[6]: https://opensource.com/article/20/5/curl-cheat-sheet
[7]: https://condor.depaul.edu/mkalin

View File

@@ -1,351 +0,0 @@
[#]: subject: (Measure your Internet of Things with Raspberry Pi and open source tools)
[#]: via: (https://opensource.com/article/21/3/iot-measure-raspberry-pi)
[#]: author: (Darin London https://opensource.com/users/dmlond)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
Measure your Internet of Things with Raspberry Pi and open source tools
======
Setting up an environment-monitoring system demonstrates how to use open
source tools to keep tabs on temperature, humidity, and more.
![Metrics and a graph illustration][1]
If you are interested in measuring and interacting with the world around you through the Internet of Things (IoT), there are a variety of inexpensive microcontrollers and microcomputers you can use. There are also many sensors available that connect to these devices to measure many aspects of the physical world.
These sensors interface with the microcontroller boards using the [I2C][2] message bus, which programs that run on the boards can access using open source libraries in [MicroPython][3], Java, C#, and other popular programming languages. These devices and libraries make it very easy to create sophisticated data-collection systems.
To demonstrate how easy and powerful this is, I built a greenhouse monitoring system using the following components that I purchased from [SparkFun][4]:
* [Raspberry Pi Zero W with headers][5]
* [Power supply][6]
* [Qwiic pHAT][7]
* [Qwiic cables][8]
* [Qwiic Environmental Combo breakout][9]
* [Qwiic ambient light detector][10]
* [32GB microSD card][11]
* [Metal standoffs][12], [screws][13], and [nuts][14]
Adafruit has very similar offerings and connection systems.
### Getting to know Prometheus
One of the first things you can do to start interacting with your world is to collect and analyze data acquired by sensors. Open source software makes it easy to collect, analyze, display, and even take action on your data.
The [Prometheus][15] family of applications makes it easy to collect, store, and analyze data as a time series of individual events. I will briefly introduce the relevant parts of the Prometheus architecture; if you would like to learn more, there are many great articles about Prometheus on Opensource.com, including [_An introduction to monitoring with Prometheus_][16] and [_Achieve high-scale application monitoring with Prometheus_][17].
The Prometheus suite includes the following applications, which can be plugged together in various ways.
#### [Prometheus][18]
The main Prometheus service is a powerful time-series database that runs on a general-purpose computer, such as a Linux machine, cloud service, or Raspberry Pi (the Raspberry Pi 4 is recommended). A Prometheus instance can be configured to regularly "scrape" various file- and network-connected exporter services (e.g., HTTP, TCP, etc.) in the [Prometheus exposition format][19]. A single Prometheus service can be configured to scrape multiple targets, each with a unique job name. A scrape target publishes data in the form of events with a user-defined name, timestamp, value, and optional set of key-value annotations. If a data source publishes data without a timestamp, the scrape's exact time is automatically added to the event when it is stored. It can also be configured to communicate with one or more Alertmanager instances running on the same host or another host on the same network.
Once events are published in a Prometheus service, they can be queried using the [Prometheus Query Language][20]. PromQL queries can be used to create tables and graphs of events. They can also be used to configure alerts, whereby a PromQL query condition's truth causes the Prometheus service to set the configured alert's firing state as `true`; this alert will remain in the firing state as long as the condition is true. Once the condition becomes false, the alert firing state is set to `false`.
Multiple instances of an exporting service can publish the same metrics but differentiated by annotations to identify the sensor. For example, if you have three greenhouse monitors, each can publish its temperature, humidity, and other metrics, annotated with something like `greenhouse=1`, `greenhouse=2`, or `greenhouse=3`. Graphs, tables, and alerts can be configured to show all instances for a particular metric or just the metrics with specific annotations.
All metrics stored in Prometheus are annotated with the job defined for the scrape target in the configuration. Every scrape target configured in a Prometheus service has a Boolean metric called `up`, which is set to `true` each time the service successfully scrapes the target and `false` when it cannot. This is a useful metric to use in PromQL queries to define alerts when a service goes down.
#### [Alertmanager][21]
The main Prometheus service does not act on alerts—it just holds the alerts' state as firing or not firing at any particular moment. The Alertmanager service works with a Prometheus service to set up notifications when alerts defined in Prometheus are firing. One or more Alertmanager services can be configured to run on general-purpose computers on the same network as the Prometheus service.
Alertmanager notifications can be configured to communicate with various external systems, including email gateways, web service endpoints, chat services, and popular ticketing systems. Each notification can be templated to use various attributes about the event, including all of its annotations, to produce the notification message.
#### [Node Exporter][22]
Node Exporter is a very simple daemon that runs on a general-purpose computer host as a web service and exports data about that host via HTTP in the Prometheus exposition format. It is programmed to produce many different metrics about its host, such as CPU and memory utilization, using logic defined for each specific host architecture (e.g., proc filesystem, Windows Registry, etc.).
A Node Exporter instance can also be configured to present one or more Prometheus exposition format compliant files on the host filesystem. This makes it useful for publishing metrics produced by another application running on the same host. The example greenhouse monitoring system uses a Python program to collect data from the sensors and produce a Prometheus-formatted export file, and Node Exporter publishes these metrics.
#### [Pushgateway][23]
A Raspberry Pi Zero, 3, or 4 can host a Node Exporter, but other microcontrollers (such as an Arduino or Raspberry Pi Pico) cannot. Pushgateway enables these devices to publish their metrics. It is a microservice that can run on another general-purpose computer host (such as a desktop, a cloud, or even a Rasberry Pi Zero, 3, or 4) and present a prometheus exposition formatted feed for a Prometheus service to scrape, and a REST API that other processes connected to its network can use to report custom metrics.
A Pushgateway instance can run on the same host as the Prometheus service or a different host on the same network. If the microprocessor can communicate with the network using the Pushgateway and Prometheus services (e.g., an Ethernet cable, WiFi, or [LoRaWAN][24]), the process running on the microcontroller can use a standard HTTP library to report metrics using the Pushgateway REST API as part of its process loop.
#### [Grafana][25]
Grafana is not part of the Prometheus suite. It is an open source observability system designed to pull in data from multiple external data sources and integrate the data into customizable visualization dashboards. Grafana can pull data in from a variety of external system types, including Prometheus. It's another powerful, open source application that you can use to create sophisticated dashboards with the data produced by your devices. Grafana can also be installed onto a general-purpose computer, such as a desktop or a Raspberry Pi Zero, 3, or 4. (I installed it on the Raspberry Pi 4 that hosts the Prometheus and Alertmanager services.)
There are plenty of tutorials available to help you get up and running with Grafana, including several on Opensource.com, such as _[The perfect combo with Prometheus and Grafana, and more industry trends][26]_ and _[Monitoring Linux performance with Grafana][27]_.
Once Grafana is installed, use your browser to navigate to the Grafana host's hostname or internet protocol address (IP) at port 3000, and log in with the default credentials (**blank** / **admin**). Make sure to change the admin password. You can then add a data source and use the menu to choose the Prometheus main server's IP or host and port. Once you add the data source, you can start to graph data from Prometheus or create dashboards.
If you are installing any of the above on a Raspberry Pi, ensure you download the [Prometheus][28] and [Grafana][29] binary distributions for your CPU's architecture. On a running Raspberry Pi, you can use either of these commands:
* `uname -m`
* `cat /proc/cpuinfo`
to get cpu architecture. It will say something like armv7.
### Connect the Raspberry Pi Zero's sensors
Once you have somewhere to store the data, you can assemble and configure the greenhouse monitoring device. I flashed the MicroSD card with the [Raspberry Pi OS Lite][30] image and configured it for [headless connection over WiFi][31]. I plugged the Qwiiic pHAT onto the Pi Zero headers and connected the Qwiic cables from the Qwiic pHAT to each of the light and environmental combo sensors. (Be sure to plug the yellow cable into the Qwiic pHAT on the side with the Pi header connection and into the sensors on the side with the I2C solder connection holes.) It is also possible to daisy-chain the sensors if you have only one Qwiic connection to your Raspberry Pi.
![Wiring architecture][32]
(Darin London, [CC BY-SA 4.0][33])
Once the Raspberry Pi is connected to the sensors, plug the SD card into its slot, connect the power supply, and power it up. It will boot up, and then you should be able to connect to the Raspberry Pi using:
```
`ssh pi@raspbberrypi.local`
```
The default password is **raspberry**, but change it to something more secure using the `passwd` command. You can also use ping on your desktop to get the host's IP address and use it instead of the `raspberrypi.local` address. (This is useful if you have multiple Pis on your network.)
### Install Node Exporter
Install the Node Exporter application on your Raspberry Pi Zero by [downloading][34] the binary distribution for your architecture from the Prometheus website. Once it is installed, [configure it as a systemd service][35] so that it automatically starts and stops with the Raspberry Pi.
### Install Python sensor libraries
Raspberry Pi OS comes with Python 3, but it does not include the libraries required to interact with the sensors. Fortunately, there are Python libraries available.
Install SparkFun's official [Qwiic_Py library][36] to access the sensors on the Environmental Combo breakout. If you are using Raspberry Pi OS Lite, you have to install [pip][37] (the Python package installer) for Python 3:
```
`sudo apt install python3-pip`
```
The light sensor does not yet have an official SparkFun or Adafruit Python package, but you can get an open source [vml6030.py package][38] from its GitHub repo and copy it to `/home/pi` to use it in your monitoring application. It is based on the official SparkFun Arduino library.
### Install the greenhouse monitor code
The `greenhouse_monitor.py` script in this project's [GitHub repo][39] uses the Python sensor libraries to append metrics for `ambient_temperature`, `ambient_humidity`, and `ambient_light` every 11 seconds to a file named `/home/pi/metrics.prom` in the format Prometheus expects:
```
#!/usr/bin/python3
from veml6030 import VEML6030
import smbus2
import qwiic_bme280
import time
import sys
def instrument_metrics(light,temp,humidity):
  metrics_out = open('/home/pi/metrics.prom', 'w+')
  print('# HELP ambient_temperature temperature in fahrenheit', flush=True, file=metrics_out)
  print('# TYPE ambient_temperature gauge', flush=True, file=metrics_out)
  print(f'ambient_temperature {temp}', flush=True, file=metrics_out)
  print('# HELP ambient_light light in lux', flush=True, file=metrics_out)
  print('# TYPE ambient_light gauge', flush=True, file=metrics_out)
  print(f'ambient_light {light}', flush=True, file=metrics_out)
  print('# HELP ambient_humidity humidity in %RH', flush=True, file=metrics_out)
  print('# TYPE ambient_humidity gauge', flush=True, file=metrics_out)
  print(f'ambient_humidity {humidity}', flush=True, file=metrics_out)
  metrics_out.close()
print("Starting Greenhouse Monitor")
bus = smbus2.SMBus(1)  # For Raspberry Pi
light_sensor = VEML6030(bus)
environment_sensor = qwiic_bme280.QwiicBme280()
if environment_sensor.is_connected() == False:
        print("The Environment Sensor isn't connected to the system. Please check your connection", file=sys.stderr)
        exit(1)
environment_sensor.begin()
while True:
        light = light_sensor.read_light()
        temp = environment_sensor.temperature_fahrenheit
        humidity = environment_sensor.humidity
        instrument_metrics(light, temp, humidity)
        time.sleep(11)
```
This can be set up as a systemd service, `/etc/systemd/system/greenhouse_montor.service`:
```
[Unit]
Description=Greenhouse Monitor
Documentation=<https://github.com/prometheus/node\_exporter>
After=network-online.target
[Service]
User=pi
Restart=on-failure
ExecStart=/home/pi/greenhouse_monitor.py
[Install]
WantedBy=multi-user.target
```
A Node Exporter can also be configured as a systemd service to publish the metrics file produced by the `greenhouse_montitor.py` script at `/etc/systemd/system/node_exporter.service`:
```
[Unit]
Description=Node Exporter
Documentation=<https://github.com/prometheus/node\_exporter>
After=network-online.target
[Service]
User=pi
Restart=on-failure
ExecStart=/usr/local/bin/node_exporter \
  --no-collector.arp \
  --no-collector.bcache \
  --no-collector.bonding \
  --no-collector.btrfs \
  --no-collector.cpu --no-collector.cpufreq --no-collector.edac --no-collector.entropy --no-collector.filefd --no-collector.hwmon --no-collector.ipvs \
  --no-collector.loadavg \
  --no-collector.mdadm \
  --no-collector.meminfo \
  --no-collector.netdev \
  --no-collector.netstat \
  --no-collector.nfs \
  --no-collector.nfsd \
  --no-collector.rapl \
  --no-collector.softnet \
  --no-collector.stat \
  --no-collector.time \
  --no-collector.timex \
  --no-collector.uname \
  --no-collector.vmstat \
  --no-collector.xfs \
  --no-collector.zfs \
  --no-collector.netclass \
  --no-collector.powersupplyclass \
  --no-collector.pressure \
  --no-collector.diskstats \
  --no-collector.filesystem \
  --no-collector.conntrack \
  --no-collector.infiniband \
  --no-collector.schedstat \
  --no-collector.sockstat \
  --no-collector.thermal_zone \
  --no-collector.udp_queues \
  --collector.textfile.directory=/home/pi
[Install]
WantedBy=multi-user.target
```
Note that you can leave off all the `--nocollector.*` arguments, and `node_exporter` will export lots of metrics about the Raspberry Pi host and the `greenhouse_monitor` data.
Once the systemd service definitions are in place, you can add and enable them using systemctl, and they will start as soon as your Raspberry Pi boots up and has a network:
```
sudo systemctl enable greenhouse_monitor.py
sudo systemctl enable node_exporter
```
You can troubleshoot these services using:
```
`sudo systemctl status $servicename`
```
The Python script and systemd service definition files are available in the [project's GitHub repo][39].
### Restart the Raspberry Pi Zero and start monitoring
When the Raspberry Pi starts, it will start `greenhouse_monitor.py` and the `node_exporter` service. You can visit the `node_exporter` service using the IP or hostname of the Raspberry Pi running the greenhouse monitor at port 9100 (e.g., `http://$ip:9100`). Refresh every 11 seconds to see new entries.
### Configure the Prometheus server scrape endpoint
Once your greenhouse monitor's Node Exporter is exporting metrics, you can configure the Prometheus service to scrape it. Add the following lines to the `prometheus.yml` configuration file within the `scrape_configs` section (replace the IP in the targets with the IP of the device running the greenhouse_monitoring service on your network):
```
 - job_name: 'greenhouse_monitor'
 
        # metrics_path defaults to '/metrics'
        # scheme defaults to 'http'.
 
        static_configs:
        - targets: ['192.168.1.12:9100']
```
Prometheus will automatically load the configuration file every few seconds and start scraping your greenhouse monitor. You can verify that it has started scraping (and get its up/down status) by visiting the Prometheus web user interface (UI) targets page at `http://$prometheus_host:9090/targets`.
If it is up (and green), you can query metrics in the Prometheus web UI graphs page `http://$prometheus_host:9090/graph`.
![Prometheus web UI graphs page][40]
(Darin London, [CC BY-SA 4.0][33])
Once you are getting data in Prometheus, you can visit the Grafana service at `http://$graphana_host:3000`. I created a dashboard called Greenhouse with the panels for the three metrics exported by the greenhouse monitor. You can set Grafana to show data in the panels using the time controls. I was able to get the values for a 24-hour period from midnight to 11:59:59pm on the same day using the format `from: YYYY-MM-DD 00:00:00` and `To: YYYY-MM-DD 23:59:59`.
![24-hour metrics][41]
(Darin London, [CC BY-SA 4.0][33])
Notice the time of day when the sun was shining through a window onto the device?
### What should you measure next?
You have a treasure-trove of data at your fingertips to examine the physical world. Next, you could [configure Alertmanager][42] to send notifications through various communication technologies (e.g., webhooks, Slack, Gmail, PagerDuty, etc.) when alerts configured in Prometheus are firing.
Now that you know how to measure your world, the question becomes: What do you want to measure?
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/3/iot-measure-raspberry-pi
作者:[Darin London][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/dmlond
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/metrics_graph_stats_blue.png?itok=OKCc_60D (Metrics and a graph illustration)
[2]: https://en.wikipedia.org/wiki/I%C2%B2C
[3]: https://micropython.org/
[4]: https://www.sparkfun.com/
[5]: https://www.sparkfun.com/products/15470
[6]: https://www.sparkfun.com/products/13831
[7]: https://www.sparkfun.com/products/15945
[8]: https://www.sparkfun.com/products/15081
[9]: https://www.sparkfun.com/products/14348
[10]: https://www.sparkfun.com/products/15436
[11]: https://www.sparkfun.com/products/14832
[12]: https://www.sparkfun.com/products/10463
[13]: https://www.sparkfun.com/products/10453
[14]: https://www.sparkfun.com/products/10454
[15]: https://prometheus.io/
[16]: https://opensource.com/article/19/11/introduction-monitoring-prometheus
[17]: https://opensource.com/article/19/10/application-monitoring-prometheus
[18]: https://prometheus.io/docs/introduction/overview/
[19]: https://github.com/prometheus/docs/blob/master/content/docs/instrumenting/exposition_formats.md
[20]: https://prometheus.io/docs/prometheus/latest/querying/basics/
[21]: https://prometheus.io/docs/alerting/latest/alertmanager/
[22]: https://prometheus.io/docs/guides/node-exporter/
[23]: https://prometheus.io/docs/practices/pushing
[24]: https://en.wikipedia.org/wiki/LoRa#LoRaWAN
[25]: https://grafana.com/
[26]: https://opensource.com/article/20/5/Prometheus-Grafana-and-more-industry-trends
[27]: https://opensource.com/article/17/8/linux-grafana
[28]: https://prometheus.io/download/
[29]: https://grafana.com/grafana/download
[30]: https://www.raspberrypi.org/software/operating-systems/
[31]: https://www.raspberrypi.org/documentation/configuration/wireless/headless.md
[32]: https://opensource.com/sites/default/files/uploads/raspberrypi-qwiic-wiring.jpg (Wiring architecture)
[33]: https://creativecommons.org/licenses/by-sa/4.0/
[34]: https://prometheus.io/docs/guides/node-exporter/#installing-and-running-the-node-exporter
[35]: https://pimylifeup.com/raspberry-pi-prometheus
[36]: https://github.com/sparkfun/Qwiic_Py
[37]: https://pypi.org/project/pip/
[38]: https://github.com/n8many/VEML6030py
[39]: https://github.com/dmlond/greenhouse
[40]: https://opensource.com/sites/default/files/pictures/prometheus-web-ui-graphs-page.png (Prometheus web UI graphs page)
[41]: https://opensource.com/sites/default/files/uploads/24-hour-metrics.png (24-hour metrics)
[42]: https://prometheus.io/docs/alerting/latest/configuration/

View File

@@ -1,268 +0,0 @@
[#]: subject: "Use FreeBSD jails on Raspberry Pi"
[#]: via: "https://opensource.com/article/21/3/bastille-raspberry-pi"
[#]: author: "Peter Czanik https://opensource.com/users/czanik"
[#]: collector: "lkxed"
[#]: translator: " "
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
Use FreeBSD jails on Raspberry Pi
======
Create and maintain your containers (aka jails) at scale on FreeBSD with Bastille.
![Parts, modules, containers for software][1]
Image by: Opensource.com
Containers became widely popular because of Docker on Linux, but there are [much earlier implementations][2], including the [jail][3] system on FreeBSD. A container is called a "jail" in FreeBSD terminology. The jail system was first released in FreeBSD 4.0 way back in 2000, and it has continuously improved since. While 20 years ago it was used mostly on large servers, now you can run it on your Raspberry Pi.
### Jails vs. containers on Linux
Container development took a very different path on FreeBSD than on Linux. On FreeBSD, containerization was developed as a strict security feature in the late '90s for virtual hosting and its flexibility grew over the years. Limiting a container's computing resources was not part of the original concept; this was added later.
When I started to use jails in production in 2001, it was quite painful. I had to prepare my own scripts to automate working with them.
On the Linux side, there were quite a few attempts at containerization, including [lxc][4].
Docker brought popularity, accessibility, and ease of use to containers. There are now many other tools on Linux (for example, I prefer to use [Podman on my laptop][5]). And Kubernetes allows you to work with containers at really large scale.
[Bastille][6] is one of several tools available in [FreeBSD ports][7] to manage jails. It is comparable to Docker or Podman and allows you to create and maintain jails at scale instead of manually. It has a template system to automatically install and configure applications within jails, similar to Dockerfile. It also supports advanced FreeBSD functionality, like ZFS or VNET.
### Install FreeBSD on Raspberry Pi
Installing [BSD on Raspberry Pi][8] is pretty similar to installing Linux. You download a compressed image from the FreeBSD website and `dd` it to an SD card. You can also use a dedicated image writer tool; there are many available for all operating systems (OS). Download and write an image from the command line with:
```
wget https://download.freebsd.org/ftp/releases/arm64/aarch64/ISO-IMAGES/13.0/FreeBSD-13.0-BETA1-arm64-aarch64-RPI.img.xz
xzcat FreeBSD-13.0-BETA1-arm64-aarch64-RPI.img.xz | dd of=/dev/XXX
```
That writes the latest beta image available for 64-bit Raspberry Pi boards; check the [download page][9] if you use another Raspberry Pi board or want to use another build. Replace `XXX` with your SD card's device name, which depends on your OS and how the card connects to your machine. I purposefully did not use a device name so that you won't overwrite anything if you just copy and paste the instructions mindlessly. I did that and was lucky to have a recent backup of my laptop, but it was *not* a pleasant experience.
Once you've written the SD card, put it in your Raspberry Pi and boot it. The first boot takes a bit longer than usual; I suspect the partition sizes are being adjusted to the SD card's size. After a while, you will receive the familiar login prompt on a good old text-based screen. The username is **root**, and the password is the same as the user name. The SSH server is enabled by default, but don't worry; the root user cannot log in. It is still a good idea to change the password to something else. The network is automatically configured by DHCP for the Ethernet connection (I did not test WiFi).
The easiest way to configure Bastille on the system is to SSH into Raspberry Pi and copy and paste the commands and configuration in this article. You have a couple of options, depending on how much you care about industry best practices or are willing to treat it as a test system. You can either enable root login in the SSHD configuration (scary, but this is what I did at first) or create a regular user that can log in remotely. In the latter case, make sure that the user is part of the "wheel" group so that it can use `su -` to become root and use Bastille:
```
root@generic:~ # adduser
Username: czanik
Full name: Peter Czanik
Uid (Leave empty for default):
Login group [czanik]:
Login group is czanik. Invite czanik into other groups? []: wheel
Login class [default]:
Shell (sh csh tcsh bash rbash git-shell nologin) [sh]: bash
Home directory [/home/czanik]:
Home directory permissions (Leave empty for default):
Use password-based authentication? [yes]:
Use an empty password? (yes/no) [no]:
Use a random password? (yes/no) [no]:
Enter password:
Enter password again:
Lock out the account after creation? [no]:
Username   : czanik
Password   : *****
Full Name  : Peter Czanik
Uid        : 1002
Class      :
Groups     : czanik wheel
Home       : /home/czanik
Home Mode  :
Shell      : /usr/local/bin/bash
Locked     : no
OK? (yes/no): yes
adduser: INFO: Successfully added (czanik) to the user database.
Add another user? (yes/no): no
Goodbye!
```
The fifth line adds the user to the wheel group. Note that you might have a different list of shells on your system, and Bash is not part of the base system. Install Bash before adding the user:
```
pkg install bash
```
PKG needs to bootstrap itself on the first run, so invoking the command takes a bit longer this time.
### Get started with Bastille
Managing jails with the tools in the FreeBSD base system is possible—but not really convenient. Using a tool like Bastille can simplify it considerably. It is not part of the base system, so install it:
```
pkg install bastille
```
As you can see from the command's output, Bastille has no external dependencies. It is a shell script that relies on commands in the FreeBSD base system (with an exception I'll note later when explaining templates).
If you want to start your containers on boot, enable Bastille:
```
sysrc bastille_enable="YES"
```
Start with a simple use case. Many people use containers to install different development tools in different containers to avoid conflicts or simplify their environments. For example, no sane person wants to install Python 2 on a brand-new system—but you might need to run an ancient script every once in a while. So, create a jail for Python 2.
Before creating your first jail, you need to bootstrap a FreeBSD release and configure networking. Just make sure that you bootstrap the same or an older release than the host is running. For example:
```
bastille bootstrap 12.2-RELEASE
```
It downloads and extracts this release under the `/usr/local/bastille` directory structure.
Networking can be configured in many different ways using Bastille. One option that works everywhere—on your local machine and in the cloud—is using cloned interfaces. This allows jails to use an internal network that does not interfere with the external network. Configure and start this internal network:
```
sysrc cloned_interfaces+=lo1
sysrc ifconfig_lo1_name="bastille0"
service netif cloneup
```
With this network setup, services in your jails are not accessible from the outside network, nor can they reach outside. You need forward ports from your host's external interface to the jails and to enable network access translation (NAT). Bastille integrates with BSD's [PF firewall][10] for this task. The following `pf.conf` configures the PF firewall such that Bastille can add port forwarding rules to the firewall dynamically:
```
ext_if="ue0"
set block-policy return
scrub in on $ext_if all fragment reassemble
set skip on lo
table <jails> persist
nat on $ext_if from <jails> to any -> ($ext_if)
rdr-anchor "rdr/*"
block in all
pass out quick modulate state
antispoof for $ext_if inet
pass in inet proto tcp from any to any port ssh flags S/SA modulate state
```
You also need to enable and start PF for these rules to take effect. Note that if you work through an SSH connection, starting PF will terminate your connection, and you will need to log in again:
```
sysrc pf_enable="YES"
service pf restart
```
### Create your first jail
To create a jail, Bastille needs a few parameters. First, it needs a name for the jail you're creating. It is an important parameter, as you will always refer to a jail by its name. I chose the name of the most famous Hungarian jail for the most elite criminals, but in real life, jail names often refer to the jail's function, like `syslogserver`. You also need to set the FreeBSD release you're using and an internet protocol (IP) address. I used a random `10.0.0.0/8` IP address range, but if your internal network already uses addresses from that, then using the `192.168.0.0/16` is probably a better idea:
```
bastille create csillag 12.2-RELEASE 10.17.89.51
```
Your new jail should be up and running within a few seconds. It is a complete FreeBSD base system without any extra packages. So install some packages, like my favorite text editor, inside the jail:
```
root@generic:~ # bastille pkg csillag install joe
[csillag]:
Updating FreeBSD repository catalogue...
FreeBSD repository is up to date.
All repositories are up to date.
The following 1 package(s) will be affected (of 0 checked):
New packages to be INSTALLED:
        joe: 4.6,1
Number of packages to be installed: 1
The process will require 2 MiB more space.
442 KiB to be downloaded.
Proceed with this action? [y/N]: y
[csillag] [1/1] Fetching joe-4.6,1.txz: 100%  442 KiB 452.5kB/s    00:01    
Checking integrity... done (0 conflicting)
[csillag] [1/1] Installing joe-4.6,1...
[csillag] [1/1] Extracting joe-4.6,1: 100%
```
You can install multiple packages at the same time. Install Python 2, Bash, and Git:
```
bastille pkg csillag install bash python2 git
```
Now you can start working in your new, freshly created jail. There are no network services installed in it, but you can reach it through its console:
```
root@generic:~ # bastille console csillag
[csillag]:
root@csillag:~ # python2
Python 2.7.18 (default, Feb  2 2021, 01:53:44)
[GCC FreeBSD Clang 10.0.1 (git@github.com:llvm/llvm-project.git llvmorg-10.0.1- on freebsd12
Type "help", "copyright", "credits" or "license" for more information.
>>>
root@csillag:~ # logout
root@generic:~ #
```
### Work with templates
The previous example manually installed some packages inside a jail. Setting up jails manually is no fun, even if Bastille makes it easy. Templates make the process even easier; they are similar to Dockerfiles but not entirely the same concept. You bootstrap templates for Bastille just like FreeBSD releases and then apply them to jails. When you apply a template, it will install the necessary packages and change configurations as needed.
To use templates, you need to install Git on the host:
```
pkg install git
```
For example, to bootstrap the `syslog-ng` template, use:
```
bastille bootstrap https://gitlab.com/BastilleBSD-Templates/syslog-ng
```
Create a new jail, apply the template, and redirect an external port to it:
```
bastille create alcatraz 12.2-RELEASE 10.17.89.50
bastille template alcatraz BastilleBSD-Templates/syslog-ng
bastille rdr alcatraz tcp 514 514
```
To test the new service within the jail, use telnet to connect port 514 of your host and enter some random text. Use the `tail` command within your jail to see what you just entered:
```
root@generic:~ # tail /usr/local/bastille/jails/alcatraz/root/var/log/messages
Feb  6 03:57:27 alcatraz sendmail[3594]: gethostbyaddr(10.17.89.50) failed: 1
Feb  6 04:07:13 alcatraz syslog-ng[1186]: Syslog connection accepted; fd='23', client='AF_INET(192.168.1.126:50104)', local='AF_INET(0.0.0.0:514)'
Feb  6 04:07:18 192.168.1.126 this is a test
Feb  6 04:07:20 alcatraz syslog-ng[1186]: Syslog connection closed; fd='23', client='AF_INET(192.168.1.126:50104)', local='AF_INET(0.0.0.0:514)'
```
Since I'm a [syslog-ng][11] evangelist, I used the syslog-ng template in my example, but there are many more available. Check the full list of [Bastille templates][12] to learn about them.
### What's next?
I hope that this article inspires you to try FreeBSD and Bastille on your Raspberry Pi. It was just enough information to get you started; to learn about all of Bastille's cool features—like auditing your jails for vulnerabilities and updating software within them—in the [documentation][13].
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/3/bastille-raspberry-pi
作者:[Peter Czanik][a]
选题:[lkxed][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/czanik
[b]: https://github.com/lkxed
[1]: https://opensource.com/sites/default/files/lead-images/containers_modules_networking_hardware_parts.png
[2]: https://opensource.com/article/18/1/history-low-level-container-runtimes
[3]: https://docs.freebsd.org/en/books/handbook/jails/
[4]: https://opensource.com/article/18/11/behind-scenes-linux-containers
[5]: https://opensource.com/article/18/10/podman-more-secure-way-run-containers
[6]: https://bastillebsd.org/
[7]: https://www.freebsd.org/ports/
[8]: https://opensource.com/article/19/3/netbsd-raspberry-pi
[9]: https://www.freebsd.org/where/
[10]: https://en.wikipedia.org/wiki/PF_(firewall)
[11]: https://www.syslog-ng.com/
[12]: https://gitlab.com/BastilleBSD-Templates/
[13]: https://bastille.readthedocs.io/en/latest/

View File

@@ -1,201 +0,0 @@
[#]: subject: (How to Install Nvidia Drivers on Linux Mint [Beginners Guide])
[#]: via: (https://itsfoss.com/nvidia-linux-mint/)
[#]: author: (Ankush Das https://itsfoss.com/author/ankush/)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
How to Install Nvidia Drivers on Linux Mint [Beginners Guide]
======
[Linux Mint][1] is a fantastic Ubuntu-based Linux distribution that aims to make it easy for newbies to experience Linux by minimizing the learning curve.
Not just limited to being one of the [best beginner-friendly Linux distros][2], it also does a [few things better than Ubuntu][3]. Of course, if youre using Linux Mint like I do, youre probably already aware of it.
We have many beginner-focused Mint tutorials on Its FOSS. Recently some readers requested help with Nvidia drivers with Linux Mint and hence I came up with this article.
I have tried to mention different methods with a bit of explaining whats going on and what you are doing in these steps.
But before that, you should know this:
* Nvidia has two categories of drivers. Open source drivers called Nouveau and proprietary drivers from Nvidia itself.
* Most of the time, Linux distributions install the open source Nouveau driver and you can manually enable the proprietary drivers.
* Graphics drivers are tricky things. For some systems, Nouveau works pretty well while for some it could create issues like blank screen or poor display. You may switch to proprietary drivers in such cases.
* The proprietary driver from Nvidia has different version numbers like 390, 450, 460. The higher the number, the more recent is the driver. Ill show you how to change between them in this tutorial.
* If you are opting for proprietary drivers, you should go with the latest one unless you encounter some graphics issue. In those cases, opt for an older version of the driver and see if that works fine for you.
Now that you have some familiarity with the terms, lets see how to go about installing Nvidia drivers on Linux Mint.
### How to Install Nvidia Drivers on Linux Mint: The Easy Way (Recommended)
Linux Mint comes baked in with a [Driver Manager][4] which easily lets you choose/install a driver that you need for your hardware using the GUI.
By default, you should see the open-source [xserver-xorg-video-nouveau][5] driver for Nvidia cards installed, and it works pretty well until you start playing a high-res video or want to play a [game on Linux][6].
So, to get the best possible experience, proprietary drivers should be preferred.
You should get different proprietary driver versions when you launch the Driver Manager as shown in the image below:
![][7]
Basically, the higher the number, the latest driver it is. At the time of writing this article, driver **version 460** was the latest recommendation for my Graphics Card. You just need to select the driver version and hit “**Apply Changes**“.
Once done, all you need to do is just reboot your system and if the driver works, you should automatically get the best resolution image and the refresh rate depending on your monitor for the display.
For instance, heres how it looks for me (while it does not detect the correct size of the monitor):
![][8]
#### Troubleshooting tips
Depending on your card, the list would appear to be different. So, **what driver version should you choose?** Here are some pointers for you:
* The latest drivers should ensure compatibility with the latest games and should technically offer better performance overall. Hence, it is the recommended solution.
* If the latest driver causes issues or fails to work, choose the next best offering. For instance, version 460 didnt work, so I tried applying driver version 450, and it worked!
Initially, in my case (**Linux Mint 20.1** with **Linux Kernel 5.4**), the latest driver 460 version did not work. Technically, it was successfully installed but did not load up every time I booted.
**What to do if drivers fail to load at boot**
_How do you know when it does not work?_ You will boot up with a low-resolution screen, and you will be unable to tweak the resolution or the refresh rate of the monitor.
It will also inform you about the same in the form of an error:
![][9]
Fortunately, a solution from [Linux Mints forum][10] solved it for me. Heres what you need to do:
1\. Access the modules file using the command:
```
xed admin:///etc/modules
```
2\. Youll be prompted to authenticate the access with your account password. Once done, you just need to add the following lines at the bottom:
```
nvidia
nvidia-drm
nvidia-modeset
```
Heres what it looks like:
![][11]
If that doesnt work, you can launch the Driver Manager and opt for another version of Nvidia driver. Its more of a hit and try.
### Install Nvidia Driver Using the Terminal (Special Use-Cases)
For some reasons, if you are not getting the latest drivers for your Graphics Card using the Driver Manager, opting for the terminal method could help.
It may not be the safest way to do it, but I did not have any issues installing the latest Nvidia driver 460 version.
Ill always recommend sticking to the Driver Manager app unless you have your reasons.
To get started, first you have to check the available drivers for your GPU. Type in the following command to get the list:
```
ubuntu-drivers devices
```
Heres how it looks in my case:
![][12]
**non-free** refers to the proprietary drivers and **free** points at the open-source nouveau Nvidia drivers.
As mentioned above, usually, it is preferred to try installing the recommended driver. In order to do that, you just type in:
```
sudo ubuntu-drivers autoinstall
```
If you want something specific, type in:
```
sudo apt install nvidia-driver-450
```
You just have to replace “**450**” with the driver version that you want and it will install the driver in the same way that you install an application via the terminal.
Once installed, you just need to restart the system or type it in the terminal:
```
reboot
```
**To check the Nvidia driver version and verify the installation, you can type the following command in the terminal:**
```
nvidia-smi
```
Heres how it may look like:
![][13]
To remove the driver and its associated dependencies, simply mention the exact version of the driver:
```
sudo apt remove nvidia-driver-450
sudo apt autoremove
```
And, simply reboot. It should fallback to use the open-source nouveau driver.
install the open-source driver using the following command and then reboot to revert to the default open-source driver:
```
sudo apt install xserver-xorg-video-nouveau
```
### Installing Nvidia Drivers using the .run file from Official Website (Time Consuming/Not Recommended)
Unless you want the latest version of the driver from the official website or just want to experiment the process, you can opt to download the file (.run) and install it.
To proceed, you need to first disable the X server and then install the Nvidia driver which could turn out to be troublesome and risky.
You can follow the [official documentation][14] if you want to explore this method, but you may not need it at all.
### Wrapping Up
While its easy to install Nvidia drivers in Linux Mint, occasionally, you might find something that does not work for your hardware.
If one driver version does not work, Id suggest you to try other available versions for your Graphics Card and stick to the one that works. Unless youre gaming and want the latest software/hardware compatibility, you dont really need the latest Nvidia drivers installed.
Feel free to share your experiences with installing Nvidia drivers on Linux Mint in the comments down below.
--------------------------------------------------------------------------------
via: https://itsfoss.com/nvidia-linux-mint/
作者:[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://linuxmint.com/
[2]: https://itsfoss.com/best-linux-beginners/
[3]: https://itsfoss.com/linux-mint-vs-ubuntu/
[4]: https://github.com/linuxmint/mintdrivers
[5]: https://nouveau.freedesktop.org/
[6]: https://itsfoss.com/linux-gaming-guide/
[7]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/03/linux-mint-driver-manager.jpg?resize=800%2C548&ssl=1
[8]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/03/linux-mint-display-settings.jpg?resize=800%2C566&ssl=1
[9]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/03/linux-mint-no-driver.jpg?resize=593%2C299&ssl=1
[10]: https://forums.linuxmint.com/viewtopic.php?p=1895521#p1895521
[11]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/03/etc-modules-nvidia.jpg?resize=800%2C587&ssl=1
[12]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/03/linux-mint-device-drivers-list.jpg?resize=800%2C506&ssl=1
[13]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/03/nvidia-smi.jpg?resize=800%2C556&ssl=1
[14]: https://download.nvidia.com/XFree86/Linux-x86_64/440.82/README/installdriver.html

View File

@@ -1,111 +0,0 @@
[#]: subject: (6 open source tools for wedding planning)
[#]: via: (https://opensource.com/article/21/3/open-source-wedding-planning)
[#]: author: (Jessica Cherry https://opensource.com/users/cherrybomb)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
6 open source tools for wedding planning
======
Create the event of your dreams with open source software.
![Outdoor wedding sign][1]
If I were to say I had planned on writing this article a year or so ago, I would be wrong. So, I'll give you a small amount of backstory about how this came to be.
On March 21st, I will be "getting married." I put that in quotes because I got married in Las Vegas on March 21, 2019. But I'm getting married again because my mom, who told us to elope, decided she was wrong and wanted a real wedding. So here I am, planning a wedding.
![Vegas wedding][2]
(Jess Cherry, [CC BY-SA 4.0][3])
Planning hasn't been smooth. We have moved the event twice due to the pandemic. My wedding planner got pregnant in the middle of it all, and since she's due in March, everything is now in my lap. About three-quarters of our invitations did not make it to their destinations because of weird mail issues, so we're sorting out our guests by text messages.
But all of my poor luck has led to this, a moment when I can share my list of open source tools that are helping me survive wedding planning, even at the last minute.
### Budgeting this whole thing
Let's talk about budgets. As seems to be typical, mine went above and beyond what I'd originally allocated. I chose [HomeBank][4], which I wrote about last year, so I am familiar with it.
I put all my wedding expenses in HomeBank as debts so that I could show my overall basic costs (not counting all the extra stuff I bought for the most expensive party I will ever throw). Once they are marked as debts, I can add a transaction and an income to it to pay for everything and keep track of what I owe.
Here's an example of what such a budgeting might look like in HomeBank.
![HomeBank][5]
(Jess Cherry, [CC BY-SA 4.0][3])
### Keep track of invitations and guests
I did not have a proper guest list at the outset, so I needed a way to manage my guests. I went with [LibreOffice Calc][6], because everyone needs sheets with counts and plans. Here is an example of what I ended up with. I used it to tally up numbers, so I could move on to planning how many tables I needed at the party. I summed the number of guests at the bottom of Column B to get the total.
![LibreOffice Calc][7]
(Jess Cherry, [CC BY-SA 4.0][3])
### Table time
Certain venues, like mine, require you to provide table arrangements a month before the event so that they can be prepared for the right amount of settings and silverware. And drinks, because that's important to have for dancing and whatnot.
The venue gave me a PDF for my table setup, but I decided to use [LibreOffice Draw][8] instead because I had an extra table I didn't need, and my counts were off due to our original guest list dropping considerably. But here's my drawing of where I want the tables to be (including the table I tossed due to our lower number of guests).
![LibreOffice Draw][9]
(Jess Cherry, [CC BY-SA 4.0][3])
### How about a timeline?
One of the major pieces of event planning is having a timeline for the day to make sure everything goes according to plan. Spoiler alert: I can promise mine won't. I asked Opensource.com's productivity expert [Kevin Sonney][10] for help finding something to help me outline the big day and the rehearsal dinner the day before.
I have two problems. One, I need to share the timeline with multiple people. Two, those people do not do computers for a living, like we do, so a heavily command-line option wouldn't work. I selected something Kevin wrote about in his [productivity article series][11] this year: KDE Plasma Kontact's [KOrganizer][12] using the timeline mode. I stacked an entire day into one timeline and produced this fancy set of blocks. (Don't mind this looking weird; it's a first draft.)
![KOrganizer][13]
(Jess Cherry, [CC BY-SA 4.0][3])
I also suggest keeping everything on your to-do lists inside KOrganizer, so you don't get lost while you're working through everything. Best of all, if you need to export all of this information and put it somewhere like a popular, regularly used application (e.g., Google, because well, it's Google), it exports and imports well.
### Open source wedding tools for the pandemic
OK, so before we all rush to judgment on this, I am aware we're still in the middle of a pandemic. The wedding planning started forever ago, and guess when the pandemic started. March… It all started in March of last year. That should tell you exactly how my plans have been going.
In case you are wondering about my backup plan (since nearly three-quarters of the original guest list can't attend), the plan is to livestream this show. This leads me to two different conversations. One, I believe this is the future of weddings because it's cool to show everyone in your life this amazing moment, so from now on, wedding planners will have to add this to their services list, pandemic or not.
Two, how can I achieve this goal of livestreaming the whole event? That's easy: I have a laptop and a camera, the DJ has clip-on microphones, and a bunch of cool people write about livestreaming all the time. [Seth Kenlon][14] wrote an entire article on [live streaming with OBS][15], so I can just walk through everything about a week before and share it out. If I decide to edit and publish the video, [Don Watkins][16] gave a great walkthrough of [Kaltura][17] to get me through the post-wedding things.
### Final thoughts
If you are good with open source software and organizing, you can be the wedding planner of anyone's dreams, or you can just plan your own wedding and stay organized. I would give bonus points to anyone who can get all of this running on a [Raspberry Pi 400][18] because that would be the easiest way to have everything with you in a package that's smaller than a laptop.
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/3/open-source-wedding-planning
作者:[Jessica Cherry][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/cherrybomb
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/wedding-sign.jpg?itok=e3zagA4b (Outdoor wedding sign)
[2]: https://opensource.com/sites/default/files/uploads/wedding.jpg (Vegas wedding)
[3]: https://creativecommons.org/licenses/by-sa/4.0/
[4]: https://opensource.com/article/20/2/open-source-homebank
[5]: https://opensource.com/sites/default/files/uploads/homebank.png (HomeBank)
[6]: https://www.libreoffice.org/discover/calc/
[7]: https://opensource.com/sites/default/files/uploads/libreofficecalc.png (LibreOffice Calc)
[8]: https://www.libreoffice.org/discover/draw/
[9]: https://opensource.com/sites/default/files/uploads/libreofficedraw.png (LibreOffice Draw)
[10]: https://opensource.com/users/ksonney
[11]: https://opensource.com/article/21/1/kde-kontact
[12]: https://kontact.kde.org/components/korganizer.html
[13]: https://opensource.com/sites/default/files/uploads/kontact-korganizer.png (KOrganizer)
[14]: https://opensource.com/users/seth
[15]: https://opensource.com/article/20/4/open-source-live-stream
[16]: https://opensource.com/users/don-watkins
[17]: https://opensource.com/article/18/9/kaltura-video-editing
[18]: https://www.raspberrypi.org/products/raspberry-pi-400/

View File

@@ -1,276 +0,0 @@
[#]: subject: (Collect sensor data with your Raspberry Pi and open source tools)
[#]: via: (https://opensource.com/article/21/3/sensor-data-raspberry-pi)
[#]: author: (Peter Czanik https://opensource.com/users/czanik)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
Collect sensor data with your Raspberry Pi and open source tools
======
Learning more about what is going on in your home is not just useful;
it's fun!
![Working from home at a laptop][1]
I have lived in 100-plus-year-old brick houses for most of my life. They look nice, they are comfortable, and usually, they are not too expensive. However, humidity is high in the winter in my climate, and mold is a recurring problem. A desktop thermometer that displays relative humidity is useful for measuring it, but it does not provide continuous monitoring.
In comes the Raspberry Pi: It is small, inexpensive, and has many sensor options, including temperature and relative humidity. It can collect data around the clock, do some alerting, and forward data for analysis.
Recently, I participated in an experiment by [miniNodes][2] to collect and process environmental data on an all-[Arm][3] network of computers. One of my network's nodes was a [Raspberry Pi][4] that collected environmental data above my desk. Once the project was over, I was allowed to keep the hardware and play with it. This became my winter holiday project. Learning [Python][5] or [Elasticsearch][6] just to know more about them is boring. Having a practical project that utilizes these technologies is not just useful but also makes learning fun.
Originally, I planned to utilize only these two technologies. Unfortunately, my good old Arm "server," an [OverDrive 1000][7] machine for developers, and my Xeon server are too loud for continuous use above my desk. I turn them on only when I need them, which means some kind of buffering is necessary when the servers are offline. Implementing buffering for Elasticsearch as a beginner Python coder looked a bit difficult. Luckily, I know a tool that can buffer data and send it to Elasticsearch: [syslog-ng][8].
### A note about licensing
Elastic, the maintainer of Elasticsearch, has recently changed the project's license from the Apache License, an extremely permissive license approved by the Open Source Initiative, to a more restrictive license "[to protect our products and brand from abuse][9]." The term "abuse" in this context refers to the tendency of companies using Elasticsearch and Kibana and providing them to customers directly as a service without collaborating with Elastic or the Elastic community (a common critique of permissive licenses). It's still unclear how this affects users, but it's an important discussion for the open source community to have, especially as cloud services become more and more common.
To keep your project open source, use Elasticsearch version 7.10 under the Apache License.
### Configure data collection
For data collection, I have a [Raspberry Pi Model 3B+][10] with the latest Raspberry Pi OS version and a set of sensors from [SparkFun][11] connected to a [Qwiic pHat][12] add-on board (this board has been discontinued, but there are more recent boards that provide the same functionality). Since monitoring GPS does not make much sense with a fixed location and there is no lightning to detect during the winter, I connected only the environmental sensor. You can collect data from the sensor using [Python scripts available on GitHub][13].
Install the Python modules locally as a user:
```
`pip3 install sparkfun-qwiic-bme280`
```
There are three example scripts you can use to check data collection. You can download them using your browser or Git:
```
`git clone https://github.com/sparkfun/Qwiic_BME280_Py/`
```
When you start the script, it will print data in a nice, human-readable format:
```
pi@raspberrypi:~/Documents/Qwiic_BME280_Py/examples $ python3 qwiic_bme280_ex1.py
SparkFun BME280 Sensor  Example 1
Humidity:       58.396
Pressure:       128911.984
Altitude:       -6818.388
Temperature:    70.43
Humidity:       58.390
Pressure:       128815.051
Altitude:       -6796.598
Temperature:    70.41
^C
Ending Example 1
```
I am from Europe, so the default temperature data did not make much sense to me. Luckily, you can easily rewrite the code to use the metric system: just replace `temperature_fahrenheit` with `temperature_celsius`. Pressure and altitude showed some crazy values, even when I changed to the metric system, but I did not debug them. The humidity and temperature values were pretty close to what I expected (based on my desktop thermometer).
Once I verified that the relevant sensors work as expected, I started to develop my own code. It is pretty simple. First, I made sure that it printed values every second to the terminal, then I added syslog support:
```
#!/usr/bin/python3
import qwiic_bme280
import time
import sys
import syslog
# initialize sensor
sensor = qwiic_bme280.QwiicBme280()
if sensor.connected == False:
  print("Sensor not connected. Exiting")
  sys.exit(1)
sensor.begin()
# collect and log time, humidity and temperature
while True:
  t = time.localtime()
  current_time = time.strftime("%H:%M:%S", t)
  current_humidity = sensor.humidity
  current_temperature = sensor.temperature_celsius
  print("time={} humidity={} temperature={}".format(current_time,current_humidity,current_temperature))
  message = "humidity=" + str(current_humidity) + " temperature=" + str(current_temperature)
  syslog.syslog(message)
  time.sleep(1)
```
As I start the Python script using the [screen][14] utility, I also print data to the terminal. Check if the collected data arrives into syslog-ng using the `tail` command:
```
pi@raspberrypi:~ $ tail -3 /var/log/messages
Jan  5 12:11:24 raspberrypi sensor2syslog_v2.py[6213]: humidity=58.294921875 temperature=21.4
Jan  5 12:11:25 raspberrypi sensor2syslog_v2.py[6213]: humidity=58.294921875 temperature=21.4
Jan  5 12:11:26 raspberrypi sensor2syslog_v2.py[6213]: humidity=58.294921875 temperature=21.39
```
### Configure Elasticsearch
The 1GB RAM in my Pi 3B+ is way too low to run Elasticsearch and [Kibana][15], so I host them on a second machine. [Installing Elasticsearch and Kibana][16] is different on every platform, so I will not cover that. What I will cover is mapping. By default, syslog-ng sends all data as text. If you want to prepare nice graphs in Kibana, you need temperature and humidity values as floating-point numbers.
You need to set up mapping before sending data from syslog-ng. The syslog-ng configuration expects that the Sensors index uses this mapping:
```
{
  "mappings": {
    "_doc": {
      "properties": {
        "@timestamp": {
          "type": "date"
        },
        "sensors": {
          "properties": {
            "humidity": {
              "type": "float"
            },
            "temperature": {
              "type": "float"
            }
          }
        }
      }
    }
  }
}
```
Elasticsearch is now ready to collect data from syslog-ng.
### Install and configure syslog-ng
Version 3.19 of syslog-ng is included in Raspberry Pi OS, but it does not yet have Elasticsearch support. Therefore, I installed the latest version of syslog-ng from an unofficial repository. First, I added the repository key:
```
`wget -qO - https://download.opensuse.org/repositories/home:/laszlo_budai:/syslog-ng/Raspbian_10/Release.key | sudo apt-key add -`
```
Then I added the following line to `/etc/apt/sources.list.d/sng.list`:
```
`deb https://download.opensuse.org/repositories/home:/laszlo_budai:/syslog-ng/Raspbian_10/ ./`
```
Finally, I updated the repositories and installed the necessary syslog-ng packages (which also removed rsyslog from the system):
```
apt-get update
apt-get install syslog-ng-mod-json syslog-ng-mod-http
```
There are many other syslog-ng subpackages, but only these two are needed to forward sensor logs to Elasticsearch.
Syslog-ng's main configuration file is `/etc/syslog-ng/syslog-ng.conf`, and you do not need to modify it. You can extend the configuration by creating new text files with a `.conf` extension under the `/etc/syslog-ng/conf.d` directory.
I created a file called `sens2elastic.conf` with the following content:
```
filter f_sensors {program("sensor2syslog_v2.py")};
parser p_kv {kv-parser(prefix("sensors."));};
destination d_sensors {
  file("/var/log/sensors" template("$(format-json @timestamp=${ISODATE} --key sensors.*)\n\n"));
  elasticsearch-http(
      index("sensors")
      type("")
      url("<http://192.168.1.129:9200/\_bulk>")
      template("$(format-json @timestamp=${ISODATE} --key sensors.*)")
      disk-buffer(
        disk-buf-size(1G)
        reliable(no)
        dir("/tmp/disk-buffer")
      )
  );
};
log {
  source(s_src);
  filter(f_sensors);
  parser(p_kv);
  destination(d_sensors);
};
```
If you are new to syslog-ng, read my article about [syslog-ng's building blocks][17] to learn about syslog-ng's configuration. The configuration snippet above shows some of the possible building blocks, except for the source, as you need to use the local log source defined in `syslog-ng.conf` (`s_src`).
The first line is a filter: it matches the program name. Mine is `sensor2syslog_v2.py`. Make sure this value is the same as the name of your Python script.
The second line is a key-value parser. By default, syslog-ng treats the message part of incoming log messages as plain text. Using this parser, you can create name-value pairs within syslog-ng from data in the log messages that you can use later when sending logs to Elasticsearch.
The next block is a bit larger. It is a destination containing two different destination drivers. The first driver saves logs to a local file in JSON format. I use this for debugging. The second driver is the Elasticsearch destination. Make sure that the index name and the URL match your environment. Using this large disk buffer, you can ensure you don't lose any data even if your Elasticsearch server is offline for days.
The last block is a bit different. It is the log statement, the part of the configuration that connects the above building blocks. The name of the source comes from the main configuration.
Save the configuration and create the `/tmp/disk-buffer/` directory. Reload syslog-ng to make the configuration live:
```
`systemctl restart syslog-ng`
```
### Test the system
The next step is to test the system. Elasticsearch is already running and prepared to receive data. Syslog-ng is configured to forward data to Elasticsearch. So, start the script to make sure data is actually collected.
For a quick test, you can start it in a terminal window. For continuous data collection, I recommend starting it from the screen utility so that it keeps running even after you disconnect from the machine. Of course, this is not fail-safe, as it will not start "automagically" on a reboot. If you want to collect data 24/7, create an init script or a systemd service file for it.
Check that logs arrive in the `/var/log/sensors` file. If it is not empty, then the filter is working as expected. Next, open Kibana. I cannot give exact instructions here, as the menu structure seems to change with each release. Create an index pattern for Kibana from the Sensors index, then change to Kibana's Discover mode, and select the freshly defined index. You should already see incoming temperature and humidity data on the screen.
You are now ready to visualize data. I used Kibana's new [Lens][18] mode to visualize temperature and humidity values. While it is not very flexible, it is definitely easier to handle than the other visualization tools in Kibana. This diagram shows the data I collected, including how values change when I ventilate my room with fresh, cold air by opening my windows.
![Graph of sensor data in Kibana Lens][19]
(Peter Czanik, [CC BY-SA 4.0][20])
### What have I learned?
My original goal was to monitor my home's relative humidity while brushing up on my Python and Elasticsearch skills. Even staying at basic levels, I now feel more comfortable working with Python and Elasticsearch.
Best of all: Not only did I practice these tools, but I also learned about relative humidity from the graphs. Previously, I often ventilated my home by opening the windows for just one or two minutes. The Kibana graphs showed that humidity went back to the original levels quite quickly after I shut the windows. When I opened the windows for five to 10 minutes instead, humidity stayed low for many hours.
### What's next?
The more adventurous can use a Raspberry Pi and sensors not just to monitor but also to control their homes. I configured everything from the ground up, but there are ready-to-use tools available such as [Home Assistant][21]. You can also configure alerting in syslog-ng to do things like [sending an alert to your Slack channel][22] if the temperature drops below a set level. There are many sensors available for the Raspberry Pi, so there are countless possibilities on both the software and hardware side.
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/3/sensor-data-raspberry-pi
作者:[Peter Czanik][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/czanik
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/wfh_work_home_laptop_work.png?itok=VFwToeMy (Working from home at a laptop)
[2]: https://www.mininodes.com/
[3]: https://www.arm.com/
[4]: https://opensource.com/resources/raspberry-pi
[5]: https://opensource.com/tags/python
[6]: https://www.elastic.co/elasticsearch/
[7]: https://softiron.com/blog/news_20160624/
[8]: https://www.syslog-ng.com/products/open-source-log-management/
[9]: https://www.elastic.co/pricing/faq/licensing
[10]: https://www.raspberrypi.org/products/raspberry-pi-3-model-b-plus/
[11]: https://www.sparkfun.com/
[12]: https://www.sparkfun.com/products/retired/15351
[13]: https://github.com/sparkfun/Qwiic_BME280_Py/
[14]: https://www.gnu.org/software/screen/
[15]: https://www.elastic.co/kibana
[16]: https://opensource.com/article/19/7/install-elasticsearch-and-kibana-linux
[17]: https://www.syslog-ng.com/community/b/blog/posts/building-blocks-of-syslog-ng
[18]: https://www.elastic.co/kibana/kibana-lens
[19]: https://opensource.com/sites/default/files/uploads/kibanalens_data.png (Graph of sensor data in Kibana Lens)
[20]: https://creativecommons.org/licenses/by-sa/4.0/
[21]: https://www.home-assistant.io/
[22]: https://www.syslog-ng.com/community/b/blog/posts/send-your-log-messages-to-slack

View File

@@ -1,180 +0,0 @@
[#]: subject: (3 open source tools for producing video tutorials)
[#]: via: (https://opensource.com/article/21/3/video-open-source-tools)
[#]: author: (Abe Kazemzadeh https://opensource.com/users/abecode)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
3 open source tools for producing video tutorials
======
Use OBS, OpenShot, and Audacity to create videos to teach your learners.
![Person reading a book and digital copy][1]
I've learned that video tutorials are a great way to teach my students, and open source tools have helped me take my video-production skills to the next level. This article will explain how to get started and add artfulness and creativity to your video tutorial projects.
I'll describe an end-to-end workflow for making video tutorials using open source tools for each subtask. For the purposes of this tutorial, making a video is the "task," and the various steps to make the video are the "subtasks." Those subtasks are video screen capture, video recording, video editing, audio recording, and effort estimation. Other tools include hardware such as cameras and microphones. My workflow also includes effort estimation as a subtask, but it's more of a general skill that parallels the idea of effort estimation when developing software.
My workflow involves recording the bulk of the video content as screen capture. I record supporting video material (known as B-roll) using a smartphone, as it is a cheap, ubiquitous video camera. Then I edit the materials together into shot sequences using a video editor.
### Advantages of video tutorials
There are many reasons to record video tutorials. Some people prefer learning with video than with text like web pages and manuals. This preference may be partly generational—my students tend to prefer (or at least appreciate) the video option.
Some modalities, like graphical user interfaces (GUIs), are easier to demonstrate with video. Video tutorials also work well for documenting open source software. Showing a convenient, standard workflow for producing software demonstration videos makes it easier for users to learn new software.
Teaching people how to make videos can help increase the number of people participating in open source software. Enabling users to record themselves using software helps them share their knowledge. Teaching people how to do basic screen capture is a good way to make it easier for users to file bug reports on open source software.
Educators are increasingly turning to tutorial videos as a way to deliver course content asynchronously. The most direct way to transition to an online classroom is to lecture over a videoconference system. Another option is the flipped classroom, which "flips" the traditional teaching method (i.e., in-class teaching followed by independent homework) by having students watch a recorded lecture on their own at home and using classroom time as a live, synchronous, interactive session for doing independent and project work. While video technologies have been evolving in the classroom for some time, the Covid-19 pandemic strongly motivated many educators, like my colleagues at the University of St. Thomas and me, to adopt video techniques when Covid-19 forced schools to close.
Previously, I worked at the University of Southern California Annenberg School of Communications and Journalism, which offered a project and an app to help citizen journalists produce higher-quality video. (A citizen journalist is not a professional journalist but uses their proximity to current events to document and share their experiences). Similarly, this article aims to help you produce artful, quality video tutorials even if you are not a professional videographer.
### Screen capture
Screen capture is the first subtask in making a video tutorial. I use the [Open Broadcaster Software][2] (OBS) suite. OBS started as a way to stream video games and has evolved into a general-purpose tool for video recording and live streaming. It is programmed using Qt, which allows it to run on different operating systems. OBS can capture content as a video file or as a live stream, but I use it to capture to a video file for creating video tutorials.
Screen capture is the natural starting place for creating things like a video tutorial for a piece of software. Still, OBS is also useful for tutorials that use physical objects, like electronics or woodworking. A simple use is to record a presentation, but it also supports webcams and switching views to combine multiple webcams and screen captures. In fact, you can combine a simple presentation with a tutorial; in this case, the presentation slides provide structure to the other tutorial content.
![OBS][3]
The main abstractions in OBS are _scenes_, and these scenes are made up of _sources_. Sources are any basic video inputs, including webcams, entire desktop displays, individual applications, and static images. Scenes are composed of one or more sources. Any individual source can be a scene, but the power and creativity of scenes come from combining sources. An example of a composite scene with two sources would be a video-captured presentation with a "talking head"—i.e., a small window inset inside the larger display with the presenter's face recorded from a webcam. In some cases, the "talking head" can help the presenter engage with the audience better, and it serves as an extra channel of information to go along with the speech's audio.
This example implements a three-scene setup: one scene is the webcam, another scene is a full desktop display capture, and the third is the display capture with a webcam video inset.
If you are using a new OBS installation, you'll see a single blank scene called "Scene" without any sources in the lower-left corner. If you have an existing OBS installation, you can start fresh by creating a new scene collection from the **Scene Collection** menu.
Start by renaming the first scene **Face** by right-clicking the scene and selecting **Rename**. Then add the webcam as a source by selecting the **+** under **Sources**, choosing **Video Capture Device**, and clicking **Create New**. Set the name to **Webcam**, and click **OK**. This opens a screen where you can select and preview the webcam to make sure it's working (which is very useful if you have more than one webcam). After you select the webcam and click **OK**, you need to resize it. This can be done manually, but it is easier to right-click, select **Transform**, and select **Fit to Screen**.
An aside on naming scenes and sources: I like to make logical distinctions between scenes (which I give abstract names like Face) and sources (which I give concrete names like Webcam #1). A naming convention like this is useful when you have multiple scenes and sources. You can always rename scenes and sources by right-clicking and selecting **Rename**, so don't worry much about naming at this stage.
Add the second scene by clicking on the **+** button below the scenes area. Name it **Desktop** (or another name that describes this screen if you have a multiple-monitor setup). Then, under **Sources**, click **+** and select **Display Capture**. Select the display you want to capture (you only have one option if you have one monitor). Resize the video to fit the screen by right-clicking the **Transform** option. If you have one monitor, you should see a trippy, recursive view of the screen capture within a screen capture within a screen capture into infinity.
For the third scene, you can use a shortcut by duplicating the last scene and adding an inset webcam. To do this, right-click on the last scene, select **Duplicate**, and name it **Desktop with Talking Head** (or something similar). Then add another source for this scene by clicking **+** under **Sources** when this source is selected, selecting **Video Capture Device**, and choosing your webcam under **Add Existing** (instead of Create New, like before). Instead of fitting the webcam to the whole screen, this time, move and stretch the webcam so that it is in the lower-right corner. Now you'll have the desktop and the webcam in the same scene.
Now that the screen capture setup is finished, you can start making a basic software tutorial. Click **Start Recording** in the lower-right corner under **Controls**, record whatever you want to show in your tutorial, and use the scene selector to control what source you are recording. Changing scenes is like making a cut when editing a video, except it happens in real time while you are doing the tutorial. Because scene transitions in OBS happen in real time, this is more time-efficient than editing your video after the fact, so I recommend you try to do most of the scene transitions in OBS.
I mentioned above that OBS recursively captures itself in a way that can best be described as "trippy." Seeing OBS in the screen capture is fine if you are demonstrating how OBS works, but if you are making a tutorial about anything else, you will not want to capture the OBS application window. There are two ways to avoid this. First, if you have a second monitor, you can capture the desktop environment on one monitor and have OBS running on the other. Second, OBS allows you to capture from individual applications (rather than the entire desktop environment), so you can specify which application you want to show in your video.
When you are finished recording, click **Stop Recording**. To find the video you recorded, use the **File** menu and select **Show Recordings**.
OBS is a powerful tool with many more features than I have described. You can learn more about adding text labels, streaming, and other features in [_Linux video editing in real time with OBS Studio_][4] and [_How to livestream games like the pros with OBS_][5]. For specific questions and technical issues, OBS has a great [online user forum][6].
### Editing video and using B-roll footage
If you make mistakes when recording the screen capture or want to shorten the video, you'll need to edit it. You also might want to edit your video to make it more creative and artful. Adding creativity is also fun, and I believe having fun is necessary for sustaining your effort over time.
For this how-to, assume the screen capture video recorded in OBS is your main video content, and you have other video recorded to enhance the tutorial's creative quality. In cinema and television jargon, the main content is called "A-roll" footage ("roll" refers to when video was captured on rolls of film), and supporting video material is called "B-roll." B-roll footage includes the surrounding environment, hands and pointing gestures, heads nodding, and static images with logos or branding. Editing B-roll footage into the main A-roll footage can make your video look more professional and give it more creative depth.
A practical use of B-roll footage is to prevent _jump cuts_, which can happen when editing two similar video clips together. For example, imagine you make a mistake while doing your screen capture, and you want to cut out that part. However, this cut will leave an awkward gap—the jump cut—between the two clips after you remove the mistake. To remove that gap, put a short clip of B-roll material between the two parts. That B-roll shot placed to fill the cut is called a cutaway shot ( here, "shot" is used as a synonym of "clip," from the verb "shooting" a movie).
B-roll footage is also used to build _shot sequences_. Just like software engineers build design patterns from individual statements, functions, and classes, videographers build shot sequences from individual shots or clips. These shot sequences enhance the video's quality and creativity.
One of these, called the five-shot sequence, makes a good opening sequence to introduce your video tutorial. As the name suggests, it consists of five shots:
1. A close up of your hands
2. A close up of your face
3. A wide shot of the environment with you in it
4. An over-the-shoulder shot showing the action as if your audience is watching over your shoulder
5. A creative shot to capture an unusual perspective or something else the audience should know
This [example][7] shows what this looks like.
Showing pictures of yourself doing the activity can also help people better imagine doing it. There is a body of research about so-called "mirror neurons" that fire when observing another person's actions, especially hand movements. The five-shot sequence is also a pattern used by professional video journalists, so using it can give your video an appearance of professionalism.
In addition to these five B-roll shots, you may want to record yourself introducing the video. This could be done in OBS using the webcam, but recording it with a smartphone camera gives you options for different views and backgrounds.
#### Record your B-roll footage
You can use a smartphone camera to capture B-roll footage for the five-shot sequence. Not only are they ubiquitous, but smartphones' connectedness makes it easy to use [filesharing applications][8] to sync your video to your editing application on your computer.
You will need a tripod with a smartphone holder if you are working alone. This allows you to set up the recording without having to hold the phone in your hand. Some tripods come with remote controls that allow you to start and stop recording (search for "selfie tripod"), but this is just a convenience. Using the smartphone's forward-facing "selfie" camera can help you monitor that the camera is aimed properly.
There will be material at the beginning and end of the recorded clip that you need to edit out. I prefer to record the five clips as separate files, and sometimes I need multiple takes to get a shot correct. A movie-making "clapper" with a dry-erase board is a piece of optional equipment that can help you keep track of B-roll footage by allowing you to write information about the shot (e.g., "hand close up, take 2"). The clapper functionality—the bar on top that makes the clap noise—is useful for synchronizing audio. This helps if you have multiple cameras and microphones, but in this simple setup, the clapper's main utility is to make you look like a serious auteur.
Once you have recorded the five shots and any other material you want (e.g., a spoken introduction), copy or sync the video files to your desktop computer to begin editing.
#### Edit your video
I use [OpenShot][9], an open source video editor. Like OBS, it is programmed in Qt, so it runs on a variety of operating systems.
![Openshot][10]
_Tracks_ are OpenShot's main abstraction, and tracks can be made up of clips of individual _project files_, including video, audio, and images.
Start with the five clips from the five-shot sequence and the video captured from OBS. To import the clips into OpenShot, drag-and-drop them into the project files area. These project files are the raw material that go into the tracks—you can think of this collection as a staging area similar to a chef collecting ingredients before cooking a dish. The clips don't need to be edited: you can edit them using OpenShot when you add them into the final video.
After adding the five clips to the project files area, drag and drop the first clip to the top track. The tracks are like layers, and the higher-numbered tracks are in front of the lower-numbered tracks, so the top track should be track four or five. Ideally, each shot of the five-shot sequence will be about two or three seconds long; if they are longer, cut out the parts you don't want.
To cut the clip, move the cursor (the blue marker on the timeline) to the place you want to cut. Right-click on the blue cursor, select **Slice All**, and then select which side you want to keep. Once you trim the clip, add the next clip to the same track, and give a bit of space after the first clip. Trim the second clip like you did the first one. After you trim both clips, slide the first clip all the way to the left to time zero on the timeline. Then, drag the second clip over the first clip so that the beginning of the second clip overlaps the end of the first clip. When you release the mouse, you'll see a blue area where the clips overlap. This blue area is a transition that OpenShot adds automatically when the clips overlap. If the overlap is not quite right, the easiest way to fix it is to separate the clips, delete the transition (select the blue area and hit the **Delete** key), and then try again. OpenShot automatically adds a transition where the shots overlap, but it won't automatically delete it when they are separated. Continue by trimming and overlapping the remaining shots of the five-shot sequence.
You can do a lot more with OpenShot transitions, and [OpenShot's user guide][11] can help you learn about the options.
Finally, add the screen capture video clip from OBS. If necessary, you can edit it in the same way, by moving the blue cursor in the timeline to where you want to trim, right-clicking the blue cursor, and selecting **Slice All**. If you need to keep both sides of the slice—for example, if you want to cut out a mistake in the middle of the video—make a slice on either side of the mistake, keep the sides, and delete the middle. This may result in a jump shot; if so, insert a clip of B-roll footage between them. I've found that a closeup shot of hands on the keyboard or an over-the-shoulder shot are good cutaways for this purpose.
This example didn't use them, but the other tracks in OpenShot can be used to add parallel video tracks (e.g., a webcam, screen capture in OBS, or material recorded with a separate camera) or to add extra audio, like background music. I've found that using a single track is most convenient for combining clips for the five-shot sequence, and using multiple tracks is best for adding a separate audio track (e.g., music that will be played throughout the whole video) or when multiple views of the same action are captured separately.
This example used OBS to capture two sources, the webcam and the screen capture, but it was all done with a single device, the computer. If you have video from another device, like a standalone camera, you might want to use two parallel tracks to combine the camera video and the screen capture. However, because OBS can capture multiple sources on one screen in real time, another option would be to use a second webcam instead of a standalone video camera. Doing all the recording in OBS and switching scenes while doing the screen capture would enable you to avoid after-the-fact editing.
### Recording and editing audio
For the audio component of the recording, your computer's built-in microphone might be fine. It is also simpler and saves money. If your computer's built-in microphone is not good enough, you may want to invest in a dedicated microphone.
Even a high-quality microphone can produce poor audio quality if you don't take some care when recording it. One issue is recording in different acoustic environments: If you record one part of the video in a completely silent environment and another part in an environment with background noise (like fans, air conditioners, or other appliances), the difference in acoustic backgrounds will be very apparent.
You might think it is better to have no background noise. While this might be true for recording music, having some ambient room noise can even out the differences between clips recorded in different acoustic environments. To do this, record about a minute of the ambient sound in the target environment. You might not end up needing it, but it is easier to make a brief audio recording at the outset if you anticipate recording in different environments.
Audio compression is another technique that can help you fix volume issues if they arise. Compression helps reduce the differences between quiet and loud audio, and it has settings to not amplify background noise. [Audacity][12] is a useful open source audio tool that includes compression.
![Multitrack suggestion][13]
Using a clapper is helpful if you plan to edit multiple simultaneous audio recordings together. You can use the sharp peak in audio volume from the clapper to synchronize different tracks because the clapping noise makes it easier to line up the different recordings.
### Estimation and planning
A related issue is estimating the time and effort required to finish tasks and projects. This can be hard for many reasons, but there are some general rules of thumb that can help you estimate the time it will take to complete a video production project.
First, as I noted, it is easier to use OBS scene transitions to switch views while recording than to edit scene transitions after the fact. If you can capture transitions while recording, you have one less task to do while editing.
Another rule of thumb is that as the amount of recorded material increases, it takes more time and effort in general. For one, recording more material takes more time. Also, more material increases the overhead of organizing and editing it. Conversely and somewhat counterintuitively, given the same amount of raw material, a shorter final project will generally take more time and effort than a longer final project. When the amount of input is constant, it is harder to edit the content down to a shorter product than if you have less of a constraint on the final video's length.
Having a plan for your video tutorial will help you stay on track and not forget any topics. A plan can range from a set of bullet points to a mindmap to a full script. Not only will the plan help guide you when you start recording, it can also help after the video is done. One way to improve your video tutorial's usefulness is to have a video table of contents, where each topic includes the timestamp when it begins. If you have a plan for your video—whether it is bullet points or a script—you will already have the video's structure, and you can just add the timestamps. Many video-sharing sites have ways to start playing a video at a specific point. For example, YouTube allows you to add an anchor hashtag to the end of a video's URL (e.g., `youtube.com/videourl#t=1m30s` would start playback 90 seconds into the video). Providing a script with the video is also useful for deaf and hard-of-hearing viewers.
### Give it a try
One great thing about open source is that there are low barriers to trying new software. Since the software is free, the main costs of making a video tutorial are the hardware—a computer for screen capture and video editing and a smartphone to record the B-roll footage.
* * *
_Acknowledgments: When I started learning about video, I benefited greatly from help from colleagues,*friends, and acquaintances. The University of St. Thomas Center for Faculty Development sponsored this work financially and my colleague Eric Level at the University of St. Thomas gave me many ideas for using video in the classrooms where we teach. My former colleagues Melissa Loudon and Andrew Lih at USC Annenberg School of Communications and Journalism taught me about citizen journalism and the five-shot sequence. My friend Matthew Lynn is a visual effects expert who helped me with time estimation and room-tone issues. Finally, the audience in the 2020 Southern California Linux Expo (SCaLE 18x) Graphics track gave me many helpful suggestions, including the video table of contents._
A look behind the scenes of Dototot's The Hello World Program, a YouTube channel aimed at computer...
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/3/video-open-source-tools
作者:[Abe Kazemzadeh][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/abecode
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/read_book_guide_tutorial_teacher_student_apaper.png?itok=_GOufk6N (Person reading a book and digital copy)
[2]: https://obsproject.com/
[3]: https://opensource.com/sites/default/files/obs-full.jpg (OBS)
[4]: https://opensource.com/life/15/12/real-time-linux-video-editing-with-obs-studio
[5]: https://opensource.com/article/17/7/obs-studio-pro-level-streaming
[6]: https://obsproject.com/forum/
[7]: https://www.youtube.com/watch?v=WnDD_59Lcas
[8]: https://opensource.com/alternatives/dropbox
[9]: https://www.openshot.org/
[10]: https://opensource.com/sites/default/files/openshot-full.jpg (Openshot)
[11]: https://www.openshot.org/user-guide/
[12]: https://www.audacityteam.org/
[13]: https://opensource.com/sites/default/files/screenshot_20210303_073557.png (Multitrack suggestion)

View File

@@ -1,248 +0,0 @@
[#]: subject: (Review of Four Hyperledger Libraries- Aries, Quilt, Ursa, and Transact)
[#]: via: (https://www.linux.com/news/review-of-four-hyperledger-libraries-aries-quilt-ursa-and-transact/)
[#]: author: (Dan Brown https://training.linuxfoundation.org/announcements/review-of-four-hyperledger-libraries-aries-quilt-ursa-and-transact/)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
Review of Four Hyperledger Libraries- Aries, Quilt, Ursa, and Transact
======
_By Matt Zand_
## **Recap**
In our two previous articles, first we covered “[Review of Five popular Hyperledger DLTs- Fabric, Besu, Sawtooth, Iroha and Indy][1]” where we discussed the following five Hyperledger Distributed Ledger Technologies (DLTs):
1. Hyperledger Indy
2. Hyperledger Fabric
3. Hyperledger Iroha
4. Hyperledger Sawtooth
5. Hyperledger Besu
Then, we moved on to our second article ([Review of three Hyperledger Tools- Caliper, Cello and Avalon][2]) where we surveyed the following three Hyperledger t     ools:
1. Hyperledger Caliper
2. Hyperledger Cello
3. Hyperledger Avalon
So in this follow-up article, we review four (as listed below) Hyperledger libraries that work very well with other Hyperledger DLTs.      As of this writing, all of these libraries are at the incubation stage except for Hyperledger Aries,      which has [graduated][3] to      active.
1. Hyperledger Aries
2. Hyperledger Quilt
3. Hyperledger Ursa
4. Hyperledger Transact
**Hyperledger Aries**
Identity has been adopted by the industry as one of the most promising use cases of DLTs. Solutions and initiatives around creating, storing, and transmitting verifiable digital credentials will result in a reusable, shared, interoperable tool kit. In response to such growing demand, Hyperledger has come up with three       projects (Hyperledger Indy, Hyperledger Iroha and Hyperledger Aries) that are specifically focused on identity management.
Hyperledger Aries is infrastructure for blockchain-rooted, peer-to-peer interactions. It includes a shared cryptographic wallet (the secure storage tech, not a UI) for blockchain clients as well as a communications protocol for allowing off-ledger interactions between those clients.      This project consumes the cryptographic support provided by Hyperledger Ursa      to provide secure secret management and decentralized key management functionality.
According to Hyperledger Aries documentation, Aries includes the following features:
* An encrypted messaging system for off-ledger interactions using multiple transport protocols between clients.
* A blockchain interface layer that is also called as a resolver. It is used for creating and signing blockchain transactions.
* A cryptographic wallet to enable secure storage of cryptographic secrets and other information that is used for building blockchain clients.
* An implementation of ZKP-capable W3C verifiable credentials with the help of the ZKP primitives that are found in Hyperledger Ursa.
* A mechanism to build API-like use cases and higher-level protocols based on secure messaging functionality.
* An implementation of the specifications of the Decentralized Key Management System (DKMS) that are being currently incubated in Hyperledger Indy.
* Initially, the generic interface of Hyperledger Aries will support the Hyperledger Indy resolver. But the interface is flexible in the sense that anyone can build a pluggable method using DID method resolvers such as Ethereum and Hyperledger Fabric, or any other DID method resolver they wish to use. These resolvers would support the resolving of transactions and other data on other ledgers.
* Hyperledger Aries will additionally provide the functionality and features outside the scope of the Hyperledger Indy ledger to be fully planned and supported. Owing to these capabilities, the community can now build core message families to facilitate interoperable interactions using a wide range of use cases that involve blockchain-based identity.
For more detailed discussion on its implementation, visit the link provided in the References section.
**Hyperledger Quilt**
The widespread adoption of blockchain technology by global businesses      has coincided with the emergence of tons of isolated and disconnected networks or ledgers. While users can easily conduct transactions within their own network or ledger, they experience technical difficultly (and in some cases impracticality) for doing transactions with parties residing      on different networks or ledgers. At best, the process of cross-ledger (or cross-network) transactions is slow, expensive, or manual. However, with the advent and adoption of Interledger Protocol (ILP), money and other forms of value can be routed, packetized, and delivered over ledgers and payment networks.
Hyperledger Quilt is a tool for      interoperability      between ledger systems and is written in Java      by implementing the ILP for atomic swaps. While the Interledger is a protocol for making transactions across ledgers, ILP is a payment protocol designed to transfer value across non-distributed and distributed ledgers. The standards and specifications of Interledger protocol are governed by the open-source community under the World Wide Web Consortium umbrella. Quilt is an enterprise-grade implementation of the ILP, and provides libraries and reference implementations for the core Interledger components used for payment networks. With the launch of Quilt, the JavaScript (Interledger.js) implementation of Interledger was maintained by the JS Foundation.
According to the Quilt documentation, as a result of ILP implementation, Quilt offers the following features:
* A framework to design higher-level use-case specific protocols.
* A set of rules to enable interoperability with basic escrow semantics.
* A standard for data packet format and a ledger-dependent independent address format to enable connectors to route payments.
For more detailed discussion on its implementation, visit the link provided in the References section.
**Hyperledger Ursa**
Hyperledger Ursa is a shared cryptographic library that      enables people (and projects) to avoid duplicating other cryptographic work and hopefully increase security in the process. The library is      an opt-in repository for Hyperledger projects (and, potentially others) to place and use crypto.
Inside Project Ursa, a complete library of modular signatures and symmetric-key primitives      is at the disposal of developers to swap in and out different cryptographic schemes through configuration and without having to modify their code. On top its base library, Ursa      also includes newer cryptography, including pairing-based, threshold, and aggregate signatures. Furthermore, the zero-knowledge primitives including SNARKs are also supported by Ursa.
According to the Ursas documentation, Ursa offers the following benefits:
* Preventing duplication of solving similar security requirements across different blockchain
* Simplifying the security audits of cryptographic operations since the code is consolidated into a single location. This reduces maintenance efforts of these libraries while improving the security footprint for developers with beginner knowledge of distributed ledger projects.
* Reviewing all cryptographic codes in a single place will reduce the likelihood of dangerous security bugs.
* Boosting cross-platform interoperability when multiple platforms, which require cryptographic verification, are using the same security protocols on both platforms.
* Enhancing the architecture via modularity of common components will pave the way for future modular distributed ledger technology platforms using common components.
* Accelerating the time to market for new projects as long as an existing security paradigm can be plugged-in without a project needing to build it themselves.
For more detailed discussion on its implementation, visit the link provided in the References section.
**Hyperledger Transact**
Hyperledger Transact, in a nutshell, makes writing distributed ledger software easier by providing a shared software library that handles the execution of smart contracts, including all aspects of scheduling, transaction dispatch, and state management. Utilizing Transact, smart contracts can be executed irrespective of DLTs being used. Specifically, Transact achieves that by offering an extensible approach to implementing new smart contract languages called “smart contract engines.” As such, each smart contract engine implements a virtual machine or interpreter that processes smart contracts.
At its core, Transact is solely a transaction processing system for state transitions. That is, s     tate data is normally stored in a key-value or an SQL database. Considering an initial state and a transaction, Transact executes the transaction to produce a new state. These state transitions are deemed “pure” because only the initial state and the transaction are used as input. (In contrast to     other systems such as Ethereum where state and block information are mixed to produce the new state). Therefore, Transact is agnostic about DLT framework features other than transaction execution and state.
According to Hyperledger Transacts documentation, Transact comes with the following components:
* **State**. The Transact state implementation provides get, set, and delete operations against a database. For the Merkle-Radix tree state implementation, the tree structure is implemented on top of LMDB or an in-memory database.
* **Context manager**. In Transact, state reads and writes are scoped (sandboxed) to a specific “context” that contains a reference to a state ID (such as a Merkle-Radix state root hash) and one or more previous contexts. The context manager implements the context lifecycle and services the calls that read, write, and delete data from state.
* **Scheduler**. This component controls the order of transactions to be executed. Concrete implementations include a serial scheduler and a parallel scheduler. Parallel transaction execution is an important innovation for increasing network throughput.
* **Executor**. The Transact executor obtains transactions from the scheduler and executes them against a specific context. Execution is handled by sending the transaction to specific execution adapters (such as ZMQ or a static in-process adapter) which, in turn, send the transaction to a specific smart contract.
* **Smart Contract Engines**. These components provide the virtual machine implementations and interpreters that run the smart contracts. Examples of engines include WebAssembly, Ethereum Virtual Machine, Sawtooth Transactions Processors, and Fabric Chaincode.
For more detailed discussion on its implementation, visit the link provided in the References section.
** Summary**
In this article, we reviewed four Hyperledger libraries that are great resources for managing Hyperledger DLTs. We started by explaining Hyperledger Aries, which is infrastructure for blockchain-rooted, peer-to-peer interactions and includes a shared cryptographic wallet for blockchain clients as well as a communications protocol for allowing off-ledger interactions between those clients. Then, we learned that Hyperledger Quilt is the interoperability tool between ledger systems and is written in Java by implementing the ILP for atomic swaps. While the Interledger is a protocol for making transactions across ledgers, ILP is a payment protocol designed to transfer value across non-distributed and distributed ledgers. We also discussed that Hyperledger Ursa is a shared cryptographic library that would enable people (and projects) to avoid duplicating other cryptographic work and hopefully increase security in the process. The library would be an opt-in repository for Hyperledger projects (and, potentially others) to place and use crypto. We concluded our article by reviewing Hyperledger Transact by which smart contracts can be executed irrespective of DLTs being used. Specifically, Transact achieves that by offering an extensible approach to implementing new smart contract languages called “smart contract engines.”
**References**
For more references on all Hyperledger projects, libraries and tools, visit the below documentation links:
1. [Hyperledger Indy Project][4]
2. [Hyperledger Fabric Project][5]
3. [Hyperledger Aries Library][6]
4. [Hyperledger Iroha Project][7]
5. [Hyperledger Sawtooth Project][8]
6. [Hyperledger Besu Project][9]
7. [Hyperledger Quilt Library][10]
8. [Hyperledger Ursa Library][11]
9. [Hyperledger Transact Library][12]
10. [Hyperledger Cactus Project][13]
11. [Hyperledger Caliper Tool][14]
12. [Hyperledger Cello Tool][15]
13. [Hyperledger Explorer Tool][16]
14. [Hyperledger Grid (Domain Specific)][17]
15. [Hyperledger Burrow Project][18]
16. [Hyperledger Avalon Tool][19]
**Resources**
* Free Training Courses from The Linux Foundation &amp; Hyperledger
* [Blockchain: Understanding Its Uses and Implications (LFS170)][20]
* [Introduction to Hyperledger Blockchain Technologies (LFS171)][21]
* [Introduction to Hyperledger Sovereign Identity Blockchain Solutions: Indy, Aries &amp; Ursa (LFS172)][22]
* [Becoming a Hyperledger Aries Developer (LFS173)][23]
* [Hyperledger Sawtooth for Application Developers (LFS174)][24]
* eLearning Courses from The Linux Foundation &amp; Hyperledger
* [Hyperledger Fabric Administration (LFS272)][25]
* [Hyperledger Fabric for Developers (LFD272)][26]
* Certification Exams from The Linux Foundation &amp; Hyperledger
* [Certified Hyperledger Fabric Administrator (CHFA)][27]
* [Certified Hyperledger Fabric Developer (CHFD)][28]
* [Hands-On Smart Contract Development with Hyperledger Fabric V2][29] Book by Matt Zand and others.
* [Essential Hyperledger Sawtooth Features for Enterprise Blockchain Developers][30]
* [Blockchain Developer Guide- How to Install Hyperledger Fabric on AWS][31]
* [Blockchain Developer Guide- How to Install and work with Hyperledger Sawtooth][32]
* [Intro to Blockchain Cybersecurity][33]
* [Intro to Hyperledger Sawtooth for System Admins][34]
* [Blockchain Developer Guide- How to Install Hyperledger Iroha on AWS][35]
* [Blockchain Developer Guide- How to Install Hyperledger Indy and Indy CLI on AWS][36]
* [Blockchain Developer Guide- How to Configure Hyperledger Sawtooth Validator and REST API on AWS][37]
* [Intro blockchain development with Hyperledger Fabric][38]
* [How to build DApps with Hyperledger Fabric][39]
* [Blockchain Developer Guide- How to Build Transaction Processor as a Service and Python Egg for Hyperledger Sawtooth][40]
* [Blockchain Developer Guide- How to Create Cryptocurrency Using Hyperledger Iroha CLI][41]
* [Blockchain Developer Guide- How to Explore Hyperledger Indy Command Line Interface][42]
* [Blockchain Developer Guide- Comprehensive Blockchain Hyperledger Developer Guide from Beginner to Advance Level][43]
* [Blockchain Management in Hyperledger for System Admins][44]
* [Hyperledger Fabric for Developers][45]
**About Author**
**Matt Zand** is a serial entrepreneur and the founder of three tech startups: [DC Web Makers][46], [Coding Bootcamps][47] and [High School Technology Services][48]. He is a leading author of [Hands-on Smart Contract Development with Hyperledger Fabric][29] book by OReilly Media. He has written more than 100 technical articles and tutorials on blockchain development for Hyperledger, Ethereum and Corda R3 platforms at sites such as IBM, SAP, Alibaba Cloud, Hyperledger, The Linux Foundation, and more. As a public speaker, he has presented webinars at many Hyperledger communities across USA and Europe     . At DC Web Makers, he leads a team of blockchain experts for consulting and deploying enterprise decentralized applications. As chief architect, he has designed and developed blockchain courses and training programs for Coding Bootcamps. He has a masters degree in business management from the University of Maryland. Prior to blockchain development and consulting, he worked as senior web and mobile App developer and consultant, angel investor, business advisor for a few startup companies. You can connect with him on [LinkedIn][49].
The post [Review of Four Hyperledger Libraries- Aries, Quilt, Ursa, and Transact][50] appeared first on [Linux Foundation Training][51].
--------------------------------------------------------------------------------
via: https://www.linux.com/news/review-of-four-hyperledger-libraries-aries-quilt-ursa-and-transact/
作者:[Dan Brown][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://training.linuxfoundation.org/announcements/review-of-four-hyperledger-libraries-aries-quilt-ursa-and-transact/
[b]: https://github.com/lujun9972
[1]: https://training.linuxfoundation.org/announcements/review-of-five-popular-hyperledger-dlts-fabric-besu-sawtooth-iroha-and-indy/
[2]: https://training.linuxfoundation.org/announcements/review-of-three-hyperledger-tools-caliper-cello-and-avalon/
[3]: https://www.hyperledger.org/blog/2021/02/26/hyperledger-aries-graduates-to-active-status-joins-indy-as-production-ready-hyperledger-projects-for-decentralized-identity
[4]: https://www.hyperledger.org/use/hyperledger-indy
[5]: https://www.hyperledger.org/use/fabric
[6]: https://www.hyperledger.org/projects/aries
[7]: https://www.hyperledger.org/projects/iroha
[8]: https://www.hyperledger.org/projects/sawtooth
[9]: https://www.hyperledger.org/projects/besu
[10]: https://www.hyperledger.org/projects/quilt
[11]: https://www.hyperledger.org/projects/ursa
[12]: https://www.hyperledger.org/projects/transact
[13]: https://www.hyperledger.org/projects/cactus
[14]: https://www.hyperledger.org/projects/caliper
[15]: https://www.hyperledger.org/projects/cello
[16]: https://www.hyperledger.org/projects/explorer
[17]: https://www.hyperledger.org/projects/grid
[18]: https://www.hyperledger.org/projects/hyperledger-burrow
[19]: https://www.hyperledger.org/projects/avalon
[20]: https://training.linuxfoundation.org/training/blockchain-understanding-its-uses-and-implications/
[21]: https://training.linuxfoundation.org/training/blockchain-for-business-an-introduction-to-hyperledger-technologies/
[22]: https://training.linuxfoundation.org/training/introduction-to-hyperledger-sovereign-identity-blockchain-solutions-indy-aries-and-ursa/
[23]: https://training.linuxfoundation.org/training/becoming-a-hyperledger-aries-developer-lfs173/
[24]: https://training.linuxfoundation.org/training/hyperledger-sawtooth-application-developers-lfs174/
[25]: https://training.linuxfoundation.org/training/hyperledger-fabric-administration-lfs272/
[26]: https://training.linuxfoundation.org/training/hyperledger-fabric-for-developers-lfd272/
[27]: https://training.linuxfoundation.org/certification/certified-hyperledger-fabric-administrator-chfa/
[28]: https://training.linuxfoundation.org/certification/certified-hyperledger-fabric-developer/
[29]: https://www.oreilly.com/library/view/hands-on-smart-contract/9781492086116/
[30]: https://weg2g.com/application/touchstonewords/article-essential-hyperledger-sawtooth-features-for-enterprise-blockchain-developers.php
[31]: https://myhsts.org/tutorial-learn-how-to-install-blockchain-hyperledger-fabric-on-amazon-web-services.php
[32]: https://myhsts.org/tutorial-learn-how-to-install-and-work-with-blockchain-hyperledger-sawtooth.php
[33]: https://learn.coding-bootcamps.com/p/learn-how-to-secure-blockchain-applications-by-examples
[34]: https://learn.coding-bootcamps.com/p/introduction-to-hyperledger-sawtooth-for-system-admins
[35]: https://myhsts.org/tutorial-learn-how-to-install-blockchain-hyperledger-iroha-on-amazon-web-services.php
[36]: https://myhsts.org/tutorial-learn-how-to-install-blockchain-hyperledger-indy-on-amazon-web-services.php
[37]: https://myhsts.org/tutorial-learn-how-to-configure-hyperledger-sawtooth-validator-and-rest-api-on-aws.php
[38]: https://learn.coding-bootcamps.com/p/live-and-self-paced-blockchain-development-with-hyperledger-fabric
[39]: https://learn.coding-bootcamps.com/p/live-crash-course-for-building-dapps-with-hyperledger-fabric
[40]: https://myhsts.org/tutorial-learn-how-to-build-transaction-processor-as-a-service-and-python-egg-for-hyperledger-sawtooth.php
[41]: https://myhsts.org/tutorial-learn-how-to-work-with-hyperledger-iroha-cli-to-create-cryptocurrency.php
[42]: https://myhsts.org/tutorial-learn-how-to-work-with-hyperledger-indy-command-line-interface.php
[43]: https://myhsts.org/tutorial-comprehensive-blockchain-hyperledger-developer-guide-for-all-professional-programmers.php
[44]: https://learn.coding-bootcamps.com/p/learn-blockchain-development-with-hyperledger-by-examples
[45]: https://learn.coding-bootcamps.com/p/hyperledger-blockchain-development-for-developers
[46]: https://blockchain.dcwebmakers.com/
[47]: http://coding-bootcamps.com/
[48]: https://myhsts.org/
[49]: https://www.linkedin.com/in/matt-zand-64047871
[50]: https://training.linuxfoundation.org/announcements/review-of-four-hyperledger-libraries-aries-quilt-ursa-and-transact/
[51]: https://training.linuxfoundation.org/

View File

@@ -1,173 +0,0 @@
[#]: subject: (Build an open source theremin)
[#]: via: (https://opensource.com/article/21/3/open-source-theremin)
[#]: author: (Gordon Haff https://opensource.com/users/ghaff)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
Build an open source theremin
======
Create your own electronic musical instrument with Open.Theremin V3.
![radio communication signals][1]
Even if you haven't heard of a [theremin][2], you're probably familiar with the [eerie electronic sound][3] it makes from watching TV shows and movies like the 1951 science fiction classic _The Day the Earth Stood Still_. Theremins have also appeared in popular music, although often in the form of a theremin variant. For example, the "theremin" in the Beach Boys' "Good Vibrations" was actually an [electro-theremin][4], an instrument played with a slider invented by trombonist Paul Tanner and amateur inventor Bob Whitsell and designed to be easier to play.
Soviet physicist Leon Theremin invented the theremin in 1920. It was one of the first electronic instruments, and Theremin introduced it to the world through his concerts in Europe and the US in the late 1920s. He patented his invention in 1928 and sold the rights to RCA. However, in the wake of the 1929 stock market crash, RCA's expensive product flopped. Theremin returned to the Soviet Union under somewhat mysterious circumstances in the late 1930s. The instrument remained relatively unknown until Robert Moog, of synthesizer fame, became interested in them as a high school student in the 1950s and started writing articles and selling kits. RA Moog, the company he founded, remains the best-known maker of commercial theremins today.
### What does this have to do with open source?
In 2008, Swiss engineer Urs Gaudenz was at a festival put on by the Swiss Mechatronic Art Society, which describes itself as a collective of engineers, hackers, scientists, and artists who collaborate on creative uses of technology. The festival included a theremin exhibit, which introduced Gaudenz to the instrument.
At a subsequent event focused on bringing together music and technology, one of the organizers told Gaudenz that there were a lot of people who wanted to build theremins from kits. Some kits existed, but they often didn't work or play well. Gaudenz set off to build an open theremin that could be played in the same manner and use the same operating principles as a traditional theremin but with a modern electronic board and microcontroller.
The [Open.Theremin][5] project (currently in version 3) is completely open source, including the microcontroller code and the [hardware files][6], which include the schematics and printed circuit board (PCB) layout. The hardware and the instructions are under GPL v3, while the [control code][7] is under LGPL v3. Therefore, the project can be assembled completely from scratch. In practice, most people will probably work from the kit available from Gaudi.ch, so that's what I'll describe in this article. There's also a completely assembled version available.
### How does a theremin work?
Before getting into the details of the Open.Theremin V3 and its assembly and use, I'll talk at a high level about how traditional theremins work.
Theremins are highly unusual in that they're played without touching the instrument directly or indirectly. They're controlled by varying your distance and hand shape from [two antennas][8], a horizontal volume loop antenna, typically on the left, and a vertical pitch antenna, typically on the right. Some theremins have a pitch antenna only—Robert Plant of Led Zeppelin played such a variant—and some, including the Open.Theremin, have additional knob controls. But hand movements associated with the volume and pitch antennas are the primary means of controlling the instrument.
I've been referring to the "antennas" because that's how everyone else refers to them. But they're not antennas in the usual sense of picking up radio waves. Each antenna acts as a plate in a capacitor. This brings us to the basic theremin operating principle: the heterodyne oscillator that mixes signals from a fixed and a variable oscillator.
Such a circuit can be implemented in various ways. The Open.Theremin uses a combination of an oscillating crystal for the fixed frequency and an LC (inductance-capacitance) oscillator tuned to a similar but different frequency for the variable oscillator. There's one circuit for volume and a second one (operating at a slightly different frequency to avoid interference) for pitch, as this functional block diagram shows.
![Theremin block diagram][9]
(Gaudi Labs, [GPL v3][10])
You play the theremin by moving or changing the shape of your hand relative to each antenna. This changes the capacitance of the LC circuit. These changes are, in turn, processed and turned into sound.
### Assembling the materials
But enough theory. For this tutorial, I'll assume you're using an Open.Theremin V3 kit. In that case, here's what you need:
* [Open.Theremin V3 kit][11]
* Arduino Uno with mounting plate
* Soldering iron and related materials (you'll want fairly fine solder; I used 0.02")
* USB printer-type cable
* Wire for grounding
* Replacement antenna mounting hardware: Socket head M3-10 bolt, washer, wing nut (x2, optional)
* Speaker or headphones (3.5mm jack)
* Tripod with standard ¼" screw
The Open.Theremin is a shield for an Arduino, which is to say it's a modular circuit board that piggybacks on the Arduino microcontroller to extend its capabilities. In this case, the Arduino handles most of the important tasks for the theremin board, such as linearizing and filtering the audio and generating the instrument's sound using stored waveforms. The waveforms can be changed in the Arduino software. The Arduino's capabilities are an important part of enabling a wholly digital theremin with good sound quality without analog parts.
The Arduino is also open source. It grew out of a 2003 project at the Interaction Design Institute Ivrea in Ivrea, Italy.
### Building the hardware
There are [good instructions][12] for building the theremin hardware on the Gaudi.ch site, so I won't take you through every step. I'll focus on the project at a high level and share some knowledge that you may find helpful.
The PCB that comes with the kit already has the integrated circuits and discrete electronics surface-mounted on the board's backside, so you don't need to worry about those (other than not damaging them). What you do need to solder to the board are the pins to attach the shield to the Arduino, four potentiometers (pots), and a couple of surface-mount LEDs and a surface-mount button on the front side.
Before going further, I should note that this is probably an intermediate-level project. There's not a lot of soldering, but some of it is fairly detailed and in close proximity to other electronics. The surface-mount LEDs and button on the front side aren't hard to solder but do take a little technique (described in the instructions on the Gaudi.ch site). Just deliberately work your way through the soldering in the suggested order. You'll want good lighting and maybe a magnifier. Carefully check that no pins are shorting other pins.
Here is what the front of the hardware looks like:
![Open.Theremin front][13]
(Gordon Haff, [CC-BY-SA 4.0][14])
This shows the backside; the pins are the interface to the Arduino.
![Open.Theremin back][15]
(Gordon Haff, [CC-BY-SA 4.0][14])
I'll return to the hardware after setting up the Arduino and its software.
### Loading the software
The Arduino part of this project is straightforward if you've done anything with an Arduino and, really, even if you haven't.
* Install the [Arduino Desktop IDE][16]
* Download the [Open.Theremin control software][7] and load it into the IDE
* Attach the Arduino to your computer with a USB cable
* Upload the software to the Arduino
It's possible to modify the Arduino's software, such as changing the stored waveforms, but I will not get into that in this article.
Power off the Arduino and carefully attach the shield. Make sure you line them up properly. (If you're uncertain, look at the Open.Theremin's [schematics][17], which show you which Arduino sockets aren't in use.)
Reconnect the USB. The red LED on the shield should come on. If it doesn't, something is wrong.
Use the Arduino Desktop IDE one more time to check out the calibration process, which, hopefully, will offer more confirmation that things are going according to plan. Here are the [detailed instructions][18].
What you're doing here is monitoring the calibration process. This isn't a real calibration because you haven't attached the antennas, and you'll have to recalibrate whenever you move the theremin. But this should give you an indication of whether the theremin is basically working.
Once you press the function button for about a second, the yellow LED should start to blink slowly, and the output from the Arduino's serial monitor should look something like the image below, which shows typical Open.Theremin calibration output. The main things that indicate a problem are frequency-tuning ranges that are either just zeros or that have a range that doesn't bound the set frequency.
![Open.Theremin calibration output][19]
(Gordon Haff, [CC-BY-SA 4.0][14])
### Completing the hardware
To finish the hardware, it's easiest if you separate the Arduino from the shield. You'll probably want to screw some sort of mounting plate to the back of the Arduino for the self-adhesive tripod mount you'll attach. Attaching the tripod mount works much better on a plate than on the Arduino board itself. Furthermore, I found that the mount's adhesive didn't work very well, and I had to use stronger glue.
Next, attach the antennas. The loop antenna goes on the left. The pitch antenna goes on the right (the shorter leg connects to the shield). Attach the supplied banana plugs to the antennas. (You need to use enough force to mate the two parts that you'll want to do it before attaching the banana plugs to the board.)
I found the kit's hardware extremely frustrating to tighten sufficiently to keep the antennas from rotating. In fact, due to the volume antenna swinging around, it ended up grounding itself on some of the conductive printing on the PCB, which led to a bit of debugging. In any case, the hardware listed in the parts list at the top of this article made it much easier for me to attach the antennas.
Attach the tripod mount to a tripod or stand of some sort, connect the USB to a power source, plug the Open.Theremin into a speaker or headset, and you're ready to go.
Well, almost. You need to ground it. Plugging the theremin into a stereo may ground it, as may the USB connection powering it. If the person playing the instrument (i.e., the player) has a strong coupling to ground, that can be sufficient. But if these circumstances don't apply, you need to ground the theremin by running a wire from the ground pad on the board to something like a water pipe. You can also connect the ground pad to the player with an antistatic wrist strap or equivalent wire. This gives the player strong capacitive coupling directly with the theremin, [which works][20] as an alternative to grounding the theremin.
At this point, recalibrate the theremin. You probably don't need to fiddle with the knobs at the start. Volume does what you'd expect. Pitch changes the "zero beat" point, i.e., where the theremin transitions from high pitched near the pitch antenna to silence near your body. Register is similar to what's called sensitivity on other theremins. Timbre selects among the different waveforms programmed into the Arduino.
There are many theremin videos online. It is _not_ an easy instrument to play well, but it is certainly fun to play with.
### The value of open
The open nature of the Open.Theremin project has enabled collaboration that would have been more difficult otherwise.
For example, Gaudenz received a great deal of feedback from people who play the theremin well, including [Swiss theremin player Coralie Ehinger][21]. Gaudenz says he really doesn't play the theremin but the help he got from players enabled him to make changes to make Open.Theremin a playable musical instrument.
Others contributed directly to the instrument design, especially the Arduino software code. Gaudenz credits [Thierry Frenkel][22] with improved volume control code. [Vincent Dhamelincourt][23] came up with the MIDI implementation. Gaudenz used circuit designs that others had created and shared, like designs [for the oscillators][24] that are a central part of the Open.Theremin board.
Open.Theremin is a great example of how open source is not just good for the somewhat abstract reasons people often mention. It can also lead to specific examples of improved collaboration and more effective design.
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/3/open-source-theremin
作者:[Gordon Haff][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/ghaff
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/sound-radio-noise-communication.png?itok=KMNn9QrZ (radio communication signals)
[2]: https://en.wikipedia.org/wiki/Theremin
[3]: https://www.youtube.com/watch?v=2tnJEqXSs24
[4]: https://en.wikipedia.org/wiki/Electro-Theremin
[5]: http://www.gaudi.ch/OpenTheremin/
[6]: https://github.com/GaudiLabs/OpenTheremin_Shield
[7]: https://github.com/GaudiLabs/OpenTheremin_V3
[8]: https://en.wikipedia.org/wiki/Theremin#/media/File:Etherwave_Theremin_Kit.jpg
[9]: https://opensource.com/sites/default/files/uploads/opentheremin_blockdiagram.png (Theremin block diagram)
[10]: https://www.gnu.org/licenses/gpl-3.0.en.html
[11]: https://gaudishop.ch/index.php/product-category/opentheremin/
[12]: https://www.gaudi.ch/OpenTheremin/images/stories/OpenTheremin/Instructions_OpenThereminV3.pdf
[13]: https://opensource.com/sites/default/files/uploads/opentheremin_front.jpg (Open.Theremin front)
[14]: https://creativecommons.org/licenses/by-sa/4.0/
[15]: https://opensource.com/sites/default/files/uploads/opentheremin_back.jpg (Open.Theremin back)
[16]: https://www.arduino.cc/en/software
[17]: https://www.gaudi.ch/OpenTheremin/index.php/opentheremin-v3/schematics
[18]: http://www.gaudi.ch/OpenTheremin/index.php/40-general/197-calibration-diagnostics
[19]: https://opensource.com/sites/default/files/uploads/opentheremin_calibration.png (Open.Theremin calibration output)
[20]: http://www.thereminworld.com/Forums/T/30525/grounding-and-alternatives-yes-a-repeat-performance--
[21]: https://youtu.be/8bxz01kN7Sw
[22]: https://theremin.tf/en/category/projects/open_theremin-projects/
[23]: https://www.gaudi.ch/OpenTheremin/index.php/opentheremin-v3/midi-implementation
[24]: http://www.gaudi.ch/OpenTheremin/index.php/home/sound-and-oscillators

View File

@@ -1,94 +0,0 @@
[#]: subject: (My review of the Raspberry Pi 400)
[#]: via: (https://opensource.com/article/21/3/raspberry-pi-400-review)
[#]: author: (Don Watkins https://opensource.com/users/don-watkins)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
My review of the Raspberry Pi 400
======
Raspberry Pi 400's support for videoconferencing is a benefit for
homeschoolers seeking inexpensive computers.
![Raspberries with pi symbol overlay][1]
The [Raspberry Pi 400][2] promises to be a boon to the homeschool market. In addition to providing an easy-to-assemble workstation that comes loaded with free software, the Pi 400 also serves as a surprisingly effective videoconferencing platform. I ordered a Pi 400 from CanaKit late last year and was eager to explore this capability.
### Easy setup
After unboxing my Pi 400, which came in this lovely package, the setup was quick and easy.
![Raspberry Pi 400 box][3]
(Don Watkins, [CC BY-SA 4.0][4])
The Pi 400 reminds me of the old Commodore 64. The keyboard and CPU are in one form factor.
![Raspberry Pi 400 keyboard][5]
(Don Watkins, [CC BY-SA 4.0][4])
The matching keyboard and mouse make this little unit both aesthetically and ergonomically appealing.
Unlike earlier versions of the Raspberry Pi, there are not many parts to assemble. I connected the mouse, power supply, and micro HDMI cable to the back of the unit.
The ports on the back of the keyboard are where things get interesting.
![Raspberry Pi 400 ports][6]
(Don Watkins, [CC BY-SA 4.0][4])
From left to right, the ports are:
* 40-pin GPIO
* MicroSD: a microSD card is the main hard drive, and it comes with a microSD card in the slot, ready for startup
* Two micro HDMI ports
* USB-C port for power
* Two USB 3.0 ports and one USB 2.0 port for the mouse
* Gigabit Ethernet port
The CPU is a Broadcom 1.8GHz 64-bit quad-core ARMv8 CPU, overclocked to make it even faster than the Raspberry Pi 4's processor.
My unit came with 4GB RAM and a stock 16GB microSD card with Raspberry Pi OS installed and ready to boot up for the first time.
### Evaluating the software and user experience
The Raspberry Pi Foundation continually improves its software. Raspberry Pi OS has various wizards to make setup easier, including ones for keyboard layout, WiFi settings, and so on.
The software included on the microSD card was the August 2020 Raspberry Pi OS release. After initial startup and setup, I connected a Logitech C270 webcam (which I regularly use with my other Linux computers) to one of the USB 3.0 ports.
The operating system recognized the Logitech webcam, but I could not get the microphone to work with [Jitsi][7]. I solved this problem by updating to the latest [Raspberry Pi OS][8] release with Linux Kernel version 5.4. This OS version includes many important features that I love, like an updated Chromium browser and Pulse Audio, which solved my webcam audio woes. I can use open source videoconferencing sites, like Jitsi, and common proprietary ones, like Google Hangouts, for video calls, but Zoom was entirely unsuccessful.
### Learning computing with the Pi
The icing on the cake is the Official Raspberry Pi Beginners Guide, a 245-page book introducing you to your new computer. Packed with informative tutorials, this book hearkens back to the days when technology _provided documentation_! For the curious mind, this book is a vitally important key to the Pi, which is best when it serves as a gateway to open source computing.
And after you become enchanted with Linux and all that it offers by using the Pi, you'll have months of exploration ahead, thanks to Opensource.com's [many Raspberry Pi articles][9].
I paid US$ 135 for my Raspberry Pi 400 because I added an optional inline power switch and an extra 32GB microSD card. Without those additional components, the unit is US$ 100. It's a steal either way and sure to provide years of fun, fast, and educational computing.
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/3/raspberry-pi-400-review
作者:[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/life-raspberrypi_0.png?itok=Kczz87J2 (Raspberries with pi symbol overlay)
[2]: https://opensource.com/article/20/11/raspberry-pi-400
[3]: https://opensource.com/sites/default/files/uploads/pi400box.jpg (Raspberry Pi 400 box)
[4]: https://creativecommons.org/licenses/by-sa/4.0/
[5]: https://opensource.com/sites/default/files/uploads/pi400-keyboard.jpg (Raspberry Pi 400 keyboard)
[6]: https://opensource.com/sites/default/files/uploads/pi400-ports.jpg (Raspberry Pi 400 ports)
[7]: https://opensource.com/article/20/5/open-source-video-conferencing
[8]: https://www.raspberrypi.org/software/
[9]: https://opensource.com/tags/raspberry-pi

View File

@@ -1,100 +0,0 @@
[#]: subject: (12 Raspberry Pi projects to try this year)
[#]: via: (https://opensource.com/articles/21/3/raspberry-pi-projects)
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
12 Raspberry Pi projects to try this year
======
There are plenty of reasons to use your Raspberry Pi at home, work, and
everywhere in between. Celebrate Pi Day by choosing one of these
projects.
![Raspberry Pi 4 board][1]
Remember when the Raspberry Pi was just a really tiny hobbyist Linux computer? Well, to the surprise of no one, the Pi's power and scope has escalated quickly. Have you got a new Raspberry Pi or an old one lying around needing something to do? If so, we have plenty of new project ideas, ranging from home automation to cross-platform coding, and even some new hardware to check out.
### Raspberry Pi at home
Although I started using the Raspberry Pi mostly for electronics projects, any spare Pi not attached to a breadboard quickly became a home server. As I decommission old units, I always look for a new reason to keep it working on something useful.
* While it's fun to make LEDs blink with a Pi, after you've finished a few basic electronics projects, it might be time to give your Pi some serious responsibilities. Predictably, it turns out that a homemade smart thermostat is substantially smarter than those you buy off the shelf. Try out ThermOS and this tutorial to [build your own multizone thermostat with a Raspberry Pi][2].
* Whether you have a child trying to focus on remote schoolwork or an adult trying to stay on task during work hours, being able to "turn off" parts of the Internet can be an invaluable feature for your home network. [The Pi-hole project][3] grants you this ability by turning your Pi into your local DNS server, which allows you to block or re-route specific sites. There's a sizable community around Pi-hole, so there are existing lists of commonly blocked sites, and several front-ends to help you interact with Pi-hole right from your Android phone.
* Some families have a complex schedule. Kids have school and afterschool activities, adults have important events to attend, anniversaries and birthdays to remember, appointments to keep, and so on. You can keep track of everything using your mobile phone, but this is the future! Shouldn't wall calendars be interactive by now?
For me, nothing is more futuristic than paper that changes its ink. Of course, we have e-ink now, and the Pi can use an e-ink display as its screen. [Build a family calendar][4] with a Pi and an e-ink display for one of the lowest-powered yet most futuristic (or magical, if you prefer) calendaring systems possible.
* There's something about the Raspberry Pi's minimal design and lack of a case that inspires you to want to build something with it. After you've built yourself a thermostat and a calendar, why not [replace your home router with a Raspberry Pi][5]? With the OpenWRT distribution, you can repurpose your Pi as a router, and with the right hardware you can even add mobile connectivity.
### Monitoring your world with the Pi
For modern technology to be truly interactive, it has to have an awareness of its environment. For instance, a display that brightens or dims based on ambient light isn't possible without useful light sensor data. Similarly, the actual _environment_ is really important to us humans, and so it helps to have technology that can monitor it for us.
* Gathering data from sensors is one of the foundations you need to understand before embarking on a home automation or Internet of Things project. The Pi can do serious computing tasks, but it's got to get its data from something. Sensors provide a Pi with data about the environment. [Learn more about the fine art of gathering data over sensors][6] so you'll be ready to monitor the physical world with your Pi.
* Once you're gathering data, you need a way to process it. The open source monitoring tool Prometheus is famous for its ability to represent complex data inputs, and so it's an ideal candidate to be your IoT (Internet of Things) aggregator. Get started now, and in no time you'll be monitoring and measuring and general data crunching with [Prometheus on a Pi][7].
* While a Pi is inexpensive and small enough to be given a single task, it's still a surprisingly powerful computer. Whether you've got one Pi monitoring a dozen other Pi units on your IoT, or whether you just have a Pi tracking the temperature of your greenhouse, sometimes it's nice to be able to check in on the Pi itself to find out what its workload is like, or where specific tasks might be able to be optimized.
Grafana is a great platform for monitoring servers, including a Raspberry Pi. [Prometheus and Grafana][8] work together to monitor all aspects of your hardware, providing a friendly dashboard so you can check in on performance and reliability at a glance.
* You can download mobile apps to help you scan your home for WiFi signal strength, or you can [build your own on a Raspberry Pi using Go][9]. The latter sounds a lot more fun than the former, and because you're writing it yourself, there's a lot more customization you can do on a Pi-based solution.
### The Pi at work
I've run file shares and development servers on Pi units at work, and I've seen them at former workplaces doing all kinds of odd jobs (I remember one that got hooked up to an espresso machine to count how many cups of coffee my department consumed each day, not for accounting purposes but for bragging rights). Ask your IT department before bringing your Pi to work, of course, but look around and see what odd job a credit-card-sized computer might be able to do for you.
* Of course you could host a website on a Raspberry Pi from the very beginning of the Pi. But as the Pi has developed, it's gotten more RAM and better processing power, and so [a dynamic website with SQLite or Postgres and Python][10] is an entirely reasonable prospect.
* Printers are infamously frustrating. Wouldn't it be nice to program [your very own print UI][11] using the amazing cross-platform framework TotalCross and a Pi? The less you have to struggle through screens of poorly designed and excessive options, the better. If you design it yourself, you can provide exactly the options your department needs, leaving the rest out of sight and out of mind.
* Containers are the latest trend in computing, but before containers there were FreeBSD jails. Jails are a great solution for running high-risk applications safely, but they can be complex to set up and maintain. However, if you install FreeBSD on your Pi and run [Bastille for jail management][12] and mix in the liberal use of jail templates, you'll find yourself using jails with the same ease you use containers on Linux.
* The "problem" with having so many tech devices around your desk is that your attention tends to get split between screens. If you'd rather be able to relax and just stare at a single screen, then you might look into the Scrcpy project, a screen copying application that [lets you access the screen of your mobile device on your Linux desktop or Pi][13]. I've tested scrcpy on a Pi 3 and a Pi 4, and the performance has surprised me each time. I use scrcpy often, but especially when I'm setting up an exciting new Edge computing node on your Pi cluster, or building my smart thermostat, or my mobile router, or whatever else.
### Get a Pi
To be fair, not everyone has a Pi. If you haven't gotten hold of a Pi yet, you might [take a look at the Pi 400][14], an ultra-portable Pi-in-a-keyboard computer. Evocative of the Commodore 64, this unique form factor is designed to make it easy for you to plug your keyboard (and the Pi inside of it) into the closest monitor and get started computing. It's fast, easy, convenient, and almost _painfully_ retro. If you don't own a Pi yet, this may well be the one to get.
What Pi projects are you working on for Pi day? Tell us in the comments.
--------------------------------------------------------------------------------
via: https://opensource.com/articles/21/3/raspberry-pi-projects
作者:[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/raspberry-pi-4_lead.jpg?itok=2bkk43om (Raspberry Pi 4 board)
[2]: https://opensource.com/article/21/3/thermostat-raspberry-pi
[3]: https://opensource.com/article/21/3/raspberry-pi-parental-control
[4]: https://opensource.com/article/21/3/family-calendar-raspberry-pi
[5]: https://opensource.com/article/21/3/router-raspberry-pi
[6]: https://opensource.com/article/21/3/sensor-data-raspberry-pi
[7]: https://opensource.com/article/21/3/iot-measure-raspberry-pi
[8]: https://opensource.com/article/21/3/raspberry-pi-grafana-cloud
[9]: https://opensource.com/article/21/3/troubleshoot-wifi-go-raspberry-pi
[10]: https://opensource.com/article/21/3/web-hosting-raspberry-pi
[11]: https://opensource.com/article/21/3/raspberry-pi-totalcross
[12]: https://opensource.com/article/21/3/bastille-raspberry-pi
[13]: https://opensource.com/article/21/3/android-raspberry-pi
[14]: https://opensource.com/article/21/3/raspberry-pi-400-review

View File

@@ -1,73 +0,0 @@
[#]: subject: (Track aircraft with a Raspberry Pi)
[#]: via: (https://opensource.com/article/21/3/tracking-flights-raspberry-pi)
[#]: author: (Patrick Easters https://opensource.com/users/patrickeasters)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
Track aircraft with a Raspberry Pi
======
Explore the open skies with a Raspberry Pi, an inexpensive radio, and
open source software.
![Airplane flying with a globe background][1]
I live near a major airport, and I frequently hear aircraft flying over my house. I also have a curious preschooler, and I find myself answering questions like, "What's that?" and "Where's that plane going?" often. While a quick internet search could answer these questions, I wanted to see if I could answer them myself.
With a Raspberry Pi, an inexpensive radio, and open source software, I can track aircraft as far as 200 miles from my house. Whether you're answering relentless questions from your kids or are just curious about what's in the sky above you, this is something you can try, too.
![Flight map][2]
(Patrick Easters, [CC BY-SA 4.0][3])
### The protocol behind it all
[ADS-B][4] is a technology that aircraft use worldwide to broadcast their location. Aircraft use position data gathered from GPS and periodically broadcast it along with speed and other telemetry so that other aircraft and ground stations can track their position.
Since this protocol is well-known and unencrypted, there are many solutions to receive and parse it, including many that are open source.
### Gathering the hardware
Pretty much any [Raspberry Pi][5] will work for this project. I've used an older Pi 1 Model B, but I'd recommend a Pi 3 or newer to ensure you can keep up with the stream of decoded ADS-B messages.
To receive the ADS-B signals, you need a software-defined radio. Thanks to ultra-cheap radio chips designed for TV tuners, there are quite a few cheap USB receivers to choose from. I use [FlightAware's ProStick Plus][6] because it has a built-in filter to weaken signals outside the 1090MHz band used for ADS-B. Filtering is important since strong signals, such as broadcast FM radio and television, can desensitize the receiver. Any receiver based on RTL-SDR should work.
You will also need an antenna for the receiver. The options are limitless here, ranging from the [more adventurous DIY options][7] to purchasing a [ready-made 1090MHz antenna][8]. Whichever route you choose, antenna placement matters most. ADS-B reception is line-of-sight, so you'll want your antenna to be as high as possible to extend your range. I have mine in my attic, but I got decent results from my house's upper floor.
### Visualizing your data with software
Now that your Pi is equipped to receive ADS-B signals, the real magic happens in the software. Two of the most commonly used open source software projects for ADS-B are [readsb][9] for decoding ADS-B messages and [tar1090][10] for visualization. Combining both provides an interactive map showing all the aircraft your Pi is tracking.
Both projects provide setup instructions, but using a prebuilt image like the [ADSBx Custom Pi Image][11] is the fastest way to get going. The ADSBx image even configures a Prometheus instance with custom metrics like aircraft count.
### Keep experimenting
If the novelty of tracking airplanes with your Raspberry Pi wears off, there are plenty of ways to keep experimenting. Try different antenna designs or find the best antenna placement to maximize the number of aircraft you see.
These are just a few of the ways to track aircraft with your Pi, and hopefully, this inspires you to try it out and learn a bit about the world of radio. Happy tracking!
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/3/tracking-flights-raspberry-pi
作者:[Patrick Easters][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/patrickeasters
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/plane_travel_world_international.png?itok=jG3sYPty (Airplane flying with a globe background)
[2]: https://opensource.com/sites/default/files/uploads/flightmap.png (Flight map)
[3]: https://creativecommons.org/licenses/by-sa/4.0/
[4]: https://en.wikipedia.org/wiki/Automatic_Dependent_Surveillance%E2%80%93Broadcast
[5]: https://www.raspberrypi.org/
[6]: https://www.amazon.com/FlightAware-FA-PROSTICKPLUS-1-Receiver-Built-Filter/dp/B01M7REJJW
[7]: http://www.radioforeveryone.com/p/easy-homemade-ads-b-antennas.html
[8]: https://www.amazon.com/s?k=1090+antenna+sma&i=electronics&ref=nb_sb_noss_2
[9]: https://github.com/wiedehopf/readsb
[10]: https://github.com/wiedehopf/tar1090
[11]: https://www.adsbexchange.com/how-to-feed/adsbx-custom-pi-image/

View File

@@ -1,204 +0,0 @@
[#]: subject: "Get started with an open source customer data platform"
[#]: via: "https://opensource.com/article/21/3/rudderstack-customer-data-platform"
[#]: author: "Amey Varangaonkar https://opensource.com/users/ameypv"
[#]: collector: "lkxed"
[#]: translator: " "
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
Get started with an open source customer data platform
======
As an open source alternative to Segment, RudderStack collects and routes event stream (or clickstream) data and automatically builds your customer data lake on your data warehouse.
![Person standing in front of a giant computer screen with numbers, data][1]
Image by: Opensource.com
[RudderStack][2] is an open source, warehouse-first customer data pipeline. It collects and routes event stream (or clickstream) data and automatically builds your customer data lake on your data warehouse.
RudderStack is commonly known as the open source alternative to the customer data platform (CDP), [Segment][3]. It provides a more secure, flexible, and cost-effective solution in comparison. You get all the CDP functionality with added security and full ownership of your customer data.
Warehouse-first tools like RudderStack are architected to build functional data lakes in the user's data warehouse. The benefits are improved data control, increased flexibility in tool use, and (frequently) lower costs. Since it's open source, you can see how complicated processes—like building your identity graph—are done without relying on a vendor's black box.
### Getting the RudderStack workspace token
Before you get started, you will need the RudderStack workspace token from your RudderStack dashboard. To get it:
1. Go to the [RudderStack dashboard][4].
2. Log in using your credentials (or sign up for an account, if you don't already have one).
![RudderStack login screen][7]
3. Once you've logged in, you should see the workspace token on your RudderStack dashboard.
![RudderStack workspace token][8]
### Installing RudderStack
Setting up a RudderStack open source instance is straightforward. You have two installation options:
1. On your Kubernetes cluster, using RudderStack's Helm charts
2. On your Docker container, using the `docker-compose` command
This tutorial explains how to use both options but assumes that you already have [Git installed on your system][9].
#### Deploying with Kubernetes
You can deploy RudderStack on your Kubernetes cluster using the [Helm][10] package manager.
*If you plan to use RudderStack in production, we strongly recommend using this method.* This is because the Docker images are updated with bug fixes more frequently than the GitHub repository (which follows a monthly release cycle).
Before you can deploy RudderStack on Kubernetes, make sure you have the following prerequisites in place:
* [Install and connect kubectl][11] to your Kubernetes cluster.
* [Install Helm][12] on your system, either through the Helm installer scripts or its package manager.
* Finally, get the workspace token from the RudderStack dashboard by following the steps in the Getting the RudderStack workspace token section.
Once you've completed all the prerequisites, deploy RudderStack on your default Kubernetes cluster:
1. Find the Helm chart required to deploy RudderStack in this [repo][13].
2. Install the Helm chart with a release name of your choice (my-release, in this example) from the root directory of the repo in the previous step:
```
$ helm install \
my-release ./ --set \
rudderWorkspaceToken="<your workspace token from RudderStack dashboard>"
```
This deploys RudderStack on your default Kubernetes cluster configured with kubectl using the workspace token you obtained from the RudderStack dashboard.
For more details on the configurable parameters in the RudderStack Helm chart or updating the versions of the images used, consult the [documentation][14].
#### Deploying with Docker
Docker is the easiest and fastest way to set up your open source RudderStack instance.
First, get the workspace token from the RudderStack dashboard by following the steps above.
Once you have the RudderStack workspace token:
1. Download the [rudder-docker.yml][15] docker-compose file required for the installation.
2. Replace `<your_workspace_token>` in this file with your RudderStack workspace token.
3. Set up RudderStack on your Docker container by running:
```
docker-compose -f rudder-docker.yml up
```
Now RudderStack should be up and running on your Docker instance.
### Verifying the installation
You can verify your RudderStack installation by sending test events using the bundled shell script:
1. Clone the GitHub repository:
```
git clone https://github.com/rudderlabs/rudder-server.git
```
2. In this tutorial, you will verify RudderStack by sending test events to Google Analytics. Make sure you have a Google Analytics account and keep the tracking ID handy. Also, note that the Google Analytics account needs to have a `Web` property.
3. In the [RudderStack hosted control plane][16]:
* Add a source on the RudderStack dashboard by following the [Adding a source and destination in RudderStack][17] guide. You can use either of RudderStack's event stream software development kits (SDKs) for sending events from your app. This example sets up the [JavaScript SDK][18] as a source on the dashboard. Note: You aren't actually installing the RudderStack JavaScript SDK on your site in this step; you are just creating the source in RudderStack.
* Configure a Google Analytics destination on the RudderStack dashboard using the instructions in the guide mentioned previously. Use the Google Analytics tracking ID you kept from step 2 of this section:
![Google Analytics tracking ID][27]
4. As mentioned before, RudderStack bundles a shell script that generates test events. Get the **Source write key** from the RudderStack dashboard:
![RudderStack source write key][28]
5. Next, run:
```
./scripts/generate-event <YOUR_WRITE_KEY> https://hosted.rudderlabs.com/v1/batch
```
6. Finally, log into your Google Analytics account and verify that the events were delivered. In your Google Analytics account, navigate to *RealTime** -> **Events**. The RealTime view is important because some dashboards can take one to two days to refresh.
### Optional: Setting up the open source control plane
RudderStack's core architecture contains two major components: the data plane and the control plane. The data plane, [rudder-server][29], delivers your event data, and the RudderStack hosted control plane manages the configuration of your sources and destinations.
However, if you want to manage the source and destination configurations locally, you can set an open source control plane in your environment using the RudderStack Config Generator. (You must have [Node.js][30] installed on your system to use it.)
Here are the steps to set up the control plane:
1. Install and set up RudderStack on the platform of your choice by following the instructions above.
2. Run the following commands in this order:
```
cd utils/config-gen
npm install
npm start
```
You should now be able to access the open source control plane at `http://localhost:3000` by default. If your setup is successful, you will see the user interface.
![RudderStack open source control plane][31]
To export the existing workspace configuration from the RudderStack-hosted control plane and have RudderStack use it, consult the [docs][32].
### RudderStack and open source
The core of RudderStack is in the [rudder-server][33] repository. It is open source, licensed under [AGPL-3.0][34]. A majority of the destination integrations live in the [rudder-transformer][35] repository. They are open source as well, licensed under the [MIT License][36]. The SDKs and instrumentation repositories, several tool and utility repositories, and even some [dbt][37] model repositories for use-cases like customer journey analysis and sessionization for the data residing in your data warehouse are open source, licensed under the MIT License, and available in the [GitHub repository][38].
You can use RudderStack's open source offering, rudder-server, on your platform of choice. There are setup guides for [Docker][39], [Kubernetes][40], [native installation][41], and [developer machines][42].
RudderStack open source offers:
1. RudderStack event stream
2. 15+ SDKs and source integrations to ingest event data
3. 80+ destination and warehouse integrations
4. Slack community support
#### RudderStack Cloud
RudderStack also offers a managed option, [RudderStack Cloud][43]. It is fast, reliable, and highly scalable with a multi-node architecture and sophisticated error-handling mechanism. You can hit peak event volume without worrying about downtime, loss of events, or latency.
Image By: (RudderStack, CC BY-SA 4.0)
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/3/rudderstack-customer-data-platform
作者:[Amey Varangaonkar][a]
选题:[lkxed][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/ameypv
[b]: https://github.com/lkxed
[1]: https://opensource.com/sites/default/files/lead-images/data_metrics_analytics_desktop_laptop.png
[2]: https://rudderstack.com/
[3]: https://segment.com/
[4]: https://app.rudderstack.com/
[7]: https://opensource.com/sites/default/files/uploads/rudderstack_login.png
[8]: https://opensource.com/sites/default/files/uploads/rudderstack_workspace-token.png
[9]: https://opensource.com/life/16/7/stumbling-git
[10]: https://helm.sh/
[11]: https://kubernetes.io/docs/tasks/tools/install-kubectl/
[12]: https://helm.sh/docs/intro/install/
[13]: https://github.com/rudderlabs/rudderstack-helm
[14]: https://docs.rudderstack.com/installing-and-setting-up-rudderstack/kubernetes
[15]: https://raw.githubusercontent.com/rudderlabs/rudder-server/master/rudder-docker.yml
[16]: https://app.rudderstack.com/
[17]: https://docs.rudderstack.com/get-started/adding-source-and-destination-rudderstack
[18]: https://docs.rudderstack.com/rudderstack-sdk-integration-guides/rudderstack-javascript-sdk
[20]: https://docs.rudderstack.com/get-started/adding-source-and-destination-rudderstack
[21]: https://docs.rudderstack.com/rudderstack-sdk-integration-guides/rudderstack-javascript-sdk
[24]: https://docs.rudderstack.com/get-started/adding-source-and-destination-rudderstack
[25]: https://docs.rudderstack.com/rudderstack-sdk-integration-guides/rudderstack-javascript-sdk
[27]: https://opensource.com/sites/default/files/uploads/googleanalyticstrackingid.png
[28]: https://opensource.com/sites/default/files/uploads/rudderstack_sourcewritekey.png
[29]: https://github.com/rudderlabs/rudder-server
[30]: https://nodejs.org/en/download/
[31]: https://opensource.com/sites/default/files/uploads/rudderstack_controlplane.png
[32]: https://docs.rudderstack.com/how-to-guides/rudderstack-config-generator
[33]: https://github.com/rudderlabs/rudder-server
[34]: https://www.gnu.org/licenses/agpl-3.0-standalone.html
[35]: https://github.com/rudderlabs/rudder-transformer
[36]: https://opensource.org/licenses/MIT
[37]: https://www.getdbt.com/
[38]: https://github.com/rudderlabs
[39]: https://docs.rudderstack.com/get-started/installing-and-setting-up-rudderstack/docker
[40]: https://docs.rudderstack.com/get-started/installing-and-setting-up-rudderstack/kubernetes
[41]: https://docs.rudderstack.com/get-started/installing-and-setting-up-rudderstack/native-installation
[42]: https://docs.rudderstack.com/get-started/installing-and-setting-up-rudderstack/developer-machine-setup
[43]: https://resources.rudderstack.com/rudderstack-cloud

View File

@@ -1,213 +0,0 @@
[#]: subject: (Managing deb Content in Foreman)
[#]: via: (https://opensource.com/article/21/3/linux-foreman)
[#]: author: (Maximilian Kolb https://opensource.com/users/kolb)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
Managing deb Content in Foreman
======
Use Foreman to serve software packages and errata for certain Linux
systems.
![Package wrapped with brown paper and red bow][1]
Foreman is a data center automation tool to deploy, configure, and patch hosts. It relies on Katello for content management, which in turn relies on Pulp to manage repositories. See [_Manage content using Pulp Debian_][2] for more information.
Pulp offers many plugins for different content types, including RPM packages, Ansible roles and collections, PyPI packages, and deb content. The latter is called the **pulp_deb** plugin.
### Content management in Foreman
The basic idea for providing content to hosts is to mirror repositories and provide content to hosts via either the Foreman server or attached Smart Proxies.
This tutorial is a step-by-step guide to adding deb content to Foreman and serving hosts running Debian 10. "Deb content" refers to software packages and errata for Debian-based Linux systems (e.g., Debian and Ubuntu). This article focuses on [Debian 10 Buster][3] but the instructions also work for [Ubuntu 20.04 Focal Fossa][4], unless noted otherwise.
### 1\. Create the operating system
#### 1.1. Create an architecture
Navigate to **Hosts &gt; Architectures** and create a new architecture (if the architecture where you want to deploy Debian 10 hosts is missing). This tutorial assumes your hosts run on the x86_64 architecture, as Foreman does.
#### 1.2. Create an installation media
Navigate to **Hosts &gt; Installation Media** and create new Debian 10 installation media. Use the upstream repository URL <http://ftp.debian.org/debian/>.
Select the Debian operating system family for either Debian or Ubuntu.
Alternatively, you can also use a Debian mirror. However, content synced via Pulp does not work for two reasons: first, the `linux` and `initrd.gz` files are not in the expected locations; second, the `Release` file is not signed.
#### 1.3. Create an operating system
Navigate to **Hosts &gt; Operating Systems** and create a new operating system called Debian 10. Use **10** as the major version and leave the minor version field blank. For Ubuntu, use **20.04** as the major version and leave the minor version field blank.
![Creating an operating system entry][5]
(Maximilian Kolb, [CC BY-SA 4.0][6])
Select the Debian operating system family for Debian or Ubuntu, and specify the release name (e.g., **Buster** for Debian 10 or **Stretch** for Debian 9). Select the default partition tables and provisioning templates, i.e., **Preseed default ***.
#### 1.4. Adapt default Preseed templates (optional)
Navigate to **Hosts &gt; Partition Tables** and **Hosts &gt; Provisioning Templates** and adapt the default **Preseed** templates if necessary. Note that you need to clone locked templates before editing them. Cloned templates will not receive updates with newer Foreman versions. All Debian-based systems use **Preseed** templates, which are included with Foreman by default.
#### 1.5. Associate the templates
Navigate to **Hosts &gt; Provisioning Templates** and search for **Preseed**. Associate all desired provisioning templates to the operating system. Then, navigate to **Hosts &gt; Operating Systems** and select **Debian 10** as the operating system. Select the **Templates** tab and associate any provisioning templates that you want.
### 2\. Synchronize content
#### 2.1. Create content credentials for Debian upstream repositories and Debian client
Navigate to **Content &gt; Content Credentials** and add the required GPG public keys as content credentials for Foreman to verify the deb packages' authenticity. To obtain the necessary GPG public keys, verify the **Release** file and export the corresponding GPG public key as follows:
* **Debian 10 main:** [code] wget <http://ftp.debian.org/debian/dists/buster/Release> &amp;&amp; wget <http://ftp.debian.org/debian/dists/buster/Release.gpg>
gpg --verify Release.gpg Release
gpg --keyserver keys.gnupg.net --recv-key 16E90B3FDF65EDE3AA7F323C04EE7237B7D453EC
gpg --keyserver keys.gnupg.net --recv-key 0146DC6D4A0B2914BDED34DB648ACFD622F3D138
gpg --keyserver keys.gnupg.net --recv-key 6D33866EDD8FFA41C0143AEDDCC9EFBF77E11517
gpg --armor --export E0B11894F66AEC98 DC30D7C23CBBABEE DCC9EFBF77E11517 &gt; debian_10_main.txt
```
* **Debian 10 security:** [code] wget <http://security.debian.org/debian-security/dists/buster/updates/Release> &amp;&amp; wget <http://security.debian.org/debian-security/dists/buster/updates/Release.gpg>
gpg --verify Release.gpg Release
gpg --keyserver keys.gnupg.net --recv-key 379483D8B60160B155B372DDAA8E81B4331F7F50
gpg --keyserver keys.gnupg.net --recv-key 5237CEEEF212F3D51C74ABE0112695A0E562B32A
gpg --armor --export EDA0D2388AE22BA9 4DFAB270CAA96DFA &gt; debian_10_security.txt
```
* **Debian 10 updates:** [code] wget <http://ftp.debian.org/debian/dists/buster-updates/Release> &amp;&amp; wget <http://ftp.debian.org/debian/dists/buster-updates/Release.gpg>
gpg --verify Release.gpg Release
gpg --keyserver keys.gnupg.net --recv-key 16E90B3FDF65EDE3AA7F323C04EE7237B7D453EC
gpg --keyserver keys.gnupg.net --recv-key 0146DC6D4A0B2914BDED34DB648ACFD622F3D138
gpg --armor --export E0B11894F66AEC98 DC30D7C23CBBABEE &gt; debian_10_updates.txt
```
* **Debian 10 client:** [code]`wget --output-document=debian_10_client.txt https://apt.atix.de/atix_gpg.pub`
```
You can select the respective ASCII-armored TXT files to upload to your Foreman instance.
#### 2.2. Create products called Debian 10 and Debian 10 client
Navigate to **Content &gt; Hosts** and create two new products.
#### 2.3. Create the necessary Debian 10 repositories
Navigate to **Content &gt; Products** and select the **Debian 10** product. Create three **deb** repositories:
* **Debian 10 main:**
* URL: `http://ftp.debian.org/debian/`
* Releases: `buster`
* Component: `main`
* Architecture: `amd64`
* **Debian 10 security:**
* URL: `http://deb.debian.org/debian-security/`
* Releases: `buster/updates`
* Component: `main`
* Architecture: `amd64`
If you want, you can add a self-hosted errata service: `https://github.com/ATIX-AG/errata_server` and `https://github.com/ATIX-AG/errata_parser`
* **Debian 10 updates:**
* URL: `http://ftp.debian.org/debian/`
* Releases: `buster-updates`
* Component: `main`
* Architecture: `amd64`
Select the content credentials that you created in step 2.1. Adjust the components and architecture as needed. Navigate to **Content &gt; Products** and select the **Debian 10 client** product. Create a **deb** repository as follows:
* **Debian 10 subscription-manager**
* URL: `https://apt.atix.de/Debian10/`
* Releases: `stable`
* Component: `main`
* Architecture: `amd64`
Select the content credentials you created in step 2.1. The Debian 10 client contains the **subscription-manager** package, which runs on each content host to receive content from the Foreman Server or an attached Smart Proxy. Navigate to [apt.atix.de][7] for further instructions.
#### 2.4. Synchronize the repositories
If you want, you can create a sync plan to sync the **Debian 10** and **Debian 10 client** products periodically. To sync the product once, click the **Select Action &gt; Sync Now** button on the **Products** page.
#### 2.5. Create content views
Navigate to **Content &gt; Content Views** and create a content view called **Debian 10** comprising the Debian upstream repositories created in the **Debian 10** product and publish a new version. Do the same for the **Debian 10 client** repository of the **Debian 10 client** product.
#### 2.6. Create a composite content view
Create a new composite content view called **Composite Debian 10** comprising the previously published **Debian 10** and **Debian 10 client** content views and publish a new version. You may optionally add other content views of your choice (e.g., Puppet).
![Composite content view][8]
(Maximilian Kolb, [CC BY-SA 4.0][6])
#### 2.7. Create an activation key
Navigate to **Content &gt; Activation Keys** and create a new activation key called **debian-10**:
* Select the **Library** lifecycle environment and add the **Composite Debian 10** content view.
* On the **Details** tab, assign the correct lifecycle environment and composite content view.
* On the **Subscriptions** tab, assign the necessary subscriptions, i.e., the **Debian 10** and **Debian 10 client** products.
### 3\. Deploy a host
#### 3.1. Enable provisioning via Port 8000
Connect to your Foreman instance via SSH and edit the following file:
```
`/etc/foreman-proxy/settings.yml`
```
Search for `:http_port: 8000` and make sure it is not commented out (i.e., the line does not start with a `#`).
#### 3.2. Create a host group
Navigate to **Configure &gt; Host Groups** and create a new host group called **Debian 10**. Check out the Foreman documentation on [creating host groups][9], and make sure to select the correct entries on the **Operating System** and **Activation Keys** tabs.
#### 3.3. Create a new host
Navigate to **Hosts &gt; Create Host** and either select the host group as described above or manually enter the identical information.
> Tip: Deploying hosts running Ubuntu 20.04 is even easier, as you can use its official installation media ISO image and do offline installations. Check out orcharhino's [Managing Ubuntu Systems Guide][10] for more information.
[ATIX][11] has developed several Foreman plugins, and is an integral part of the [Foreman open source ecosystem][12]. The community's feedback on our contributions is passed back to our customers, as we continuously strive to improve our downstream product, [orcharhino][13].
This May I started my internship at Red Hat with the Pulp team . Since it was my first ever...
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/3/linux-foreman
作者:[Maximilian Kolb][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/kolb
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/brown-package-red-bow.jpg?itok=oxZYQzH- (Package wrapped with brown paper and red bow)
[2]: https://opensource.com/article/20/10/pulp-debian
[3]: https://wiki.debian.org/DebianBuster
[4]: https://releases.ubuntu.com/20.04/
[5]: https://opensource.com/sites/default/files/uploads/foreman-debian_content_deb_operating_system_entry.png (Creating an operating system entry)
[6]: https://creativecommons.org/licenses/by-sa/4.0/
[7]: https://apt.atix.de/
[8]: https://opensource.com/sites/default/files/uploads/foreman-debian_content_deb_composite_content_view.png (Composite content view)
[9]: https://docs.theforeman.org/nightly/Managing_Hosts/index-foreman-el.html#creating-a-host-group
[10]: https://docs.orcharhino.com/or/docs/sources/usage_guides/managing_ubuntu_systems_guide.html#musg_deploy_hosts
[11]: https://atix.de/
[12]: https://theforeman.org/2020/10/atix-in-the-foreman-community.html
[13]: https://orcharhino.com/

View File

@@ -1,104 +0,0 @@
[#]: subject: (6 WordPress plugins for restaurants and retailers)
[#]: via: (https://opensource.com/article/21/3/wordpress-plugins-retail)
[#]: author: (Don Watkins https://opensource.com/users/don-watkins)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
6 WordPress plugins for restaurants and retailers
======
The end of the pandemic won't be the end of curbside pickup, delivery,
and other shopping conveniences, so set your website up for success with
these plugins.
![An open for business sign.][1]
The pandemic changed how many people prefer to do business—probably permanently. Restaurants and other local retail establishments can no longer rely on walk-in trade, as they always have. Online ordering of food and other items has become the norm and the expectation. It is unlikely consumers will turn their backs on the convenience of e-commerce once the pandemic is over.
WordPress is a great platform for getting your business' message out to consumers and ensuring you're meeting their e-commerce needs. And its ecosystem of plugins extends the platform to increase its usefulness to you and your customers.
The six open source plugins described below will help you create a WordPress site that meets your customers' preferences for online shopping, curbside pickup, and delivery, and build your brand and your customer base—now and post-pandemic.
### E-commerce
![WooCommerce][2]
WooCommerce (Don Watkins, [CC BY-SA 4.0][3])
[WooCommerce][4] says it is the most popular e-commerce plugin for the WordPress platform. Its website says: "Our core platform is free, flexible, and amplified by a global community. The freedom of open source means you retain full ownership of your store's content and data forever." The plugin, which is under active development, enables you to create enticing web storefronts. It was created by WordPress developer [Automattic][5] and is released under the GPLv3.
### Order, delivery, and pickup
![Curbside Pickup][6]
Curbside Pickup (Don Watkins, [CC BY-SA 4.0][3])
[Curbside Pickup][7] is a complete system to manage your curbside pickup experience. It's ideal for any restaurant, library, retailer, or other organization that offers curbside pickup for purchases. The plugin, which is licensed GPLv3, works with any theme that supports WooCommerce.
![Food Store][8]
[Food Store][9]
If you're looking for an online food delivery and pickup system, [Food Store][9] could meet your needs. It extends WordPress' core functions and capabilities to convert your brick-and-mortar restaurant into a food-ordering hub. The plugin, licensed under GPLv2, is under active development with over 1,000 installations.
![RestroPress][10]
[RestroPress][11]
[RestroPress][11] is another option to add a food-ordering system to your website. The GPLv2-licensed plugin has over 4,000 installations and supports payment through PayPal, Amazon, and cash on delivery.
![RestaurantPress][12]
[RestaurantPress][13]
If you want to post the menu for your restaurant, bar, or cafe online, try [RestaurantPress][13]. According to its website, the plugin, which is available under a GPLv2 license, "provides modern responsive menu templates that adapt to any devices," according to its website. It has over 2,000 installations and integrates with WooCommerce.
### Communications
![Corona Virus \(COVID-19\) Banner & Live Data][14]
Corona Virus (COVID-19) Banner &amp; Live Data (Don Watkins, [CC BY-SA 4.0][3])
You can keep your customers informed about COVID-19 policies with the [Corona Virus Banner &amp; Live Data][15] plugin. It adds a simple banner with live coronavirus information to your website. It has over 6,000 active installations and is open source under GPLv2.
![MailPoet][16]
MailPoet (Don Watkins, [CC BY-SA 4.0][3])
As rules and restrictions change rapidly, an email newsletter is a great way to keep your customers informed. The [MailPoet][17] WordPress plugin makes it easy to manage and email information about new offerings, hours, and more. Through MailPoet, website visitors can subscribe to your newsletter, which you can create and send with WordPress. It has over 300,000 installations and is open source under GPLv2.
### Prepare for the post-pandemic era
Pandemic-driven lockdowns made online shopping, curbside pickup, and home delivery necessities, but these shopping trends are not going anywhere. As the pandemic subsides, restrictions will ease, and we will start shopping, dining, and doing business in person more. Still, consumers have come to appreciate the ease and convenience of e-commerce, even for small local restaurants and stores, and these plugins will help your WordPress site meet their needs.
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/3/wordpress-plugins-retail
作者:[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/open_business_sign_store.jpg?itok=g4QibRqg (An open for business sign.)
[2]: https://opensource.com/sites/default/files/pictures/woocommerce.png (WooCommerce)
[3]: https://creativecommons.org/licenses/by-sa/4.0/
[4]: https://wordpress.org/plugins/woocommerce/
[5]: https://automattic.com/
[6]: https://opensource.com/sites/default/files/pictures/curbsidepickup.png (Curbside Pickup)
[7]: https://wordpress.org/plugins/curbside-pickup/
[8]: https://opensource.com/sites/default/files/pictures/food-store.png (Food Store)
[9]: https://wordpress.org/plugins/food-store/
[10]: https://opensource.com/sites/default/files/pictures/restropress.png (RestroPress)
[11]: https://wordpress.org/plugins/restropress/
[12]: https://opensource.com/sites/default/files/pictures/restaurantpress.png (RestaurantPress)
[13]: https://wordpress.org/plugins/restaurantpress/
[14]: https://opensource.com/sites/default/files/pictures/covid19updatebanner.png (Corona Virus (COVID-19) Banner & Live Data)
[15]: https://wordpress.org/plugins/corona-virus-covid-19-banner/
[16]: https://opensource.com/sites/default/files/pictures/mailpoet1.png (MailPoet)
[17]: https://wordpress.org/plugins/mailpoet/

View File

@@ -1,144 +0,0 @@
[#]: subject: (Productivity with Ulauncher)
[#]: via: (https://fedoramagazine.org/ulauncher-productivity/)
[#]: author: (Troy Curtis Jr https://fedoramagazine.org/author/troycurtisjr/)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
Productivity with Ulauncher
======
![Productivity with Ulauncher][1]
Photo by [Freddy Castro][2] on [Unsplash][3]
Application launchers are a category of productivity software that not everyone is familiar with, and yet most people use the basic concepts without realizing it. As the name implies, this software launches applications, but they also other capablities.
Examples of dedicated Linux launchers include [dmenu][4], [Synapse][5], and [Albert][6]. On MacOS, some examples are [Quicksilver][7] and [Alfred][8]. Many modern desktops include basic versions as well. On Fedora Linux, the Gnome 3 [activities overview][9] uses search to open applications and more, while MacOS has the built-in launcher Spotlight.
While these applications have great feature sets, this article focuses on productivity with [Ulauncher][10].
### What is Ulauncher?
[Ulauncher][10] is a new application launcher written in Python, with the first Fedora package available in March 2020 for [Fedora Linux 32][11]. The core focuses on basic functionality with a nice [interface for extensions][12]. Like most application launchers, the key idea in Ulauncher is search. Search is a powerful productivity boost, especially for repetitive tasks.
Typical menu-driven interfaces work great for discovery when you arent sure what options are available. However, when the same action needs to happen repeatedly, it is a real time sink to navigate into 3 nested sub-menus over and over again. On the other side, [hotkeys][13] give immediate access to specific actions, but can be difficult to remember. Especially after exhausting all the obvious mnemonics. Is [_Control+C_][14] “copy”, or is it “cancel”? Search is a middle ground giving a means to get to a specific command quickly, while supporting discovery by typing only some remembered word or fragment. Exploring by search works especially well if tags and descriptions are available. Ulauncher supplies the search framework that extensions can use to build all manner of productivity enhancing actions.
### Getting started
Getting the core functionality of Ulauncher on any Fedora OS is trivial; install using _[dnf][15]_:
```
sudo dnf install ulauncher
```
Once installed, use any standard desktop launching method for the first start up of Ulauncher. A basic dialog should pop up, but if not try launching it again to toggle the input box on. Click the gear icon on the right side to open the preferences dialog.
![Ulauncher input box][16]
A number of options are available, but the most important when starting out are _Launch at login_ and the hotkey. The default hotkey is _Control+space_, but it can be changed. Running in Wayland needs additional configuration for consistent operation; see the [Ulauncher wiki][17] for details. Users of “Focus on Hover” or “Sloppy Focus” should also enable the “Dont hide after losing mouse focus” option. Otherwise, Ulauncher disappears while typing in some cases.
### Ulauncher basics
The idea of any application launcher, like Ulauncher, is fast access at any time. Press the hotkey and the input box shows up on top of the current application. Type out and execute the desired command and the dialog hides until the next use. Unsurprisingly, the most basic operation is launching applications. This is similar to most modern desktop environments. Hit the hotkey to bring up the dialog and start typing, for example _te_, and a list of matches comes up. Keep typing to further refine the search, or navigate to the entry using the arrow keys. For even faster access, use _Alt+#_ to directly choose a result.
![Ulauncher dialog searching for keywords with “te”][18]
Ulauncher can also do quick calculations and navigate the file-system. To calculate, hit the hotkey and type a math expression. The result list dynamically updates with the result, and hitting _Enter_ copies the value to the clipboard. Start file-system navigation by typing _/_ to start at the root directory or _~/_ to start in the home directory. Selecting a directory lists that directorys contents and typing another argument filters the displayed list. Locate the right file by repeatedly descending directories. Selecting a file opens it, while _Alt+Enter_ opens the folder containing the file.
### Ulauncher shortcuts
The first bit of customization comes in the form of shortcuts. The _Shortcuts_ tab in the preferences dialog lists all the current shortcuts. Shortcuts can be direct commands, URL aliases, URLs with argument substitution, or small scripts. Basic shortcuts for Wikipedia, StackOverflow, and Google come pre-configured, but custom shortcuts are easy to add.
![Ulauncher shortcuts preferences tab][19]
For instance, to create a duckduckgo search shortcut, click _Add Shortcut_ in the _Shortcuts_ preferences tab and add the name and keyword _duck_ with the query _<https://duckduckgo.com/?q=%s>_. Any argument given to the _duck_ keyword replaces _%s_ in the query and the URL opened in the default browser. Now, typing _duck fedora_ will bring up a duckduckgo search using the supplied terms, in this case _fedora_.
A more complex shortcut is a script to convert [UTC time][20] to local time. Once again click _Add Shortcut_ and this time use the keyword _utc_. In the _Query or Script_ text box, include the following script:
```
#!/bin/bash
tzdate=$(date -d "$1 UTC")
zenity --info --no-wrap --text="$tzdate"
```
This script takes the first argument (given as _$1_) and uses the standard [_date_][21] utility to convert a given UTC time into the computers local timezone. Then [zenity][22] pops up a simple dialog with the result. To test this, open Ulauncher and type _utc 11:00_. While this is a good example showing whats possible with shortcuts, see the [ultz][23] extension for really converting time zones.
### Introducing extensions
While the built-in functionality is great, installing extensions really accelerates productivity with Ulauncher. Extensions can go far beyond what is possible with custom shortcuts, most obviously by providing suggestions as arguments are typed. Extensions are Python modules which use the [Ulauncher extension interface][12] and can either be personally-developed local code or shared with others using GitHub. A collection of community developed extensions is available at <https://ext.ulauncher.io/>. There are basic standalone extensions for quick conversions and dynamic interfaces to online resources such as dictionaries. Other extensions integrate with external applications, like password managers, browsers, and VPN providers. These effectively give external applications a Ulauncher interface. By keeping the core code small and relying on extensions to add advanced functionality, Ulauncher ensures that each user only installs the functionality they need.
![Ulauncher extension configuration][24]
Installing a new extension is easy, though it could be a more integrated experience. After finding an interesting extension, either on the Ulauncher extensions website or anywhere on GitHub, navigate to the _Extensions_ tab in the preferences window. Click _Add Extension_ and paste in the GitHub URL. This loads the extension and shows a preferences page for any available options. A nice hint is that while browsing the extensions website, clicking on the _Github star_ button opens the extensions GitHub page. Often this GitHub repository has more details about the extension than the summary provided on the community extensions website.
#### Firefox bookmarks search
One useful extension is [Ulauncher Firefox Bookmarks][25], which gives fuzzy search access to the current users Firefox bookmarks. While this is similar to typing _*&lt;search-term&gt;_ in Firefoxs omnibar, the difference is Ulauncher gives quick access to the bookmarks from anywhere, without needing to open Firefox first. Also, since this method uses search to locate bookmarks, no folder organization is really needed. This means pages can be “starred” quickly in Firefox and there is no need to hunt for an appropriate folder to put it in.
![Firefox Ulauncher extension searching for fedora][26]
#### Clipboard search
Using a clipboard manager is a productivity boost on its own. These managers maintain a history of clipboard contents, which makes it easy to retrieve earlier copied snippets. Knowing there is a history of copied data allows the user to copy text without concern of overwriting the current contents. Adding in the [Ulauncher clipboard][27] extension gives quick access to the clipboard history with search capability without having to remember another unique hotkey combination. The extension integrates with different clipboard managers: [GPaste][28], [clipster][29], or [CopyQ][30]. Invoking Ulauncher and typing the _c_ keywords brings up a list of recent copied snippets. Typing out an argument starts to narrow the list of options, eventually showing the sought after text. Selecting the item copies it to the clipboard, ready to paste into another application.
![Ulauncher clipboard extension listing latest clipboard contents][31]
#### Google search
The last extension to highlight is [Google Search][32]. While a Google search shortcut is available as a default shortcut, using an extension allows for more dynamic behavior. With the extension, Google supplies suggestions as the search term is typed. The experience is similar to what is available on Googles homepage, or in the search box in Firefox. Again, the key benefit of using the extension for Google search is immediate access while doing anything else on the computer.
![Google search Ulauncher extension listing suggestions for fedora][33]
### Being productive
Productivity on a computer means customizing the environment for each particular usage. A little configuration streamlines common tasks. Dedicated hotkeys work really well for the most frequent actions, but it doesnt take long before it gets hard to remember them all. Using fuzzy search to find half-remembered keywords strikes a good balance between discoverability and direct access. The key to productivity with Ulauncher is identifying frequent actions and installing an extension, or adding a shortcut, to make doing it faster. Building a habit to search in Ulauncher first means there is a quick and consistent interface ready to go a key stroke away.
--------------------------------------------------------------------------------
via: https://fedoramagazine.org/ulauncher-productivity/
作者:[Troy Curtis Jr][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://fedoramagazine.org/author/troycurtisjr/
[b]: https://github.com/lujun9972
[1]: https://fedoramagazine.org/wp-content/uploads/2021/03/ulauncher-816x345.jpg
[2]: https://unsplash.com/@readysetfreddy?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText
[3]: https://unsplash.com/?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText
[4]: https://tools.suckless.org/dmenu/
[5]: https://launchpad.net/synapse-project
[6]: https://github.com/albertlauncher/albert
[7]: https://qsapp.com/
[8]: https://www.alfredapp.com/
[9]: https://help.gnome.org/misc/release-notes/3.6/users-activities-overview.html.en
[10]: https://ulauncher.io/
[11]: https://fedoramagazine.org/announcing-fedora-32/
[12]: http://docs.ulauncher.io/en/latest/
[13]: https://en.wikipedia.org/wiki/Keyboard_shortcut
[14]: https://en.wikipedia.org/wiki/Control-C
[15]: https://fedoramagazine.org/managing-packages-fedora-dnf/
[16]: https://fedoramagazine.org/wp-content/uploads/2021/03/image.png
[17]: https://github.com/Ulauncher/Ulauncher/wiki/Hotkey-In-Wayland
[18]: https://fedoramagazine.org/wp-content/uploads/2021/03/image-1.png
[19]: https://fedoramagazine.org/wp-content/uploads/2021/03/image-2-1024x361.png
[20]: https://www.timeanddate.com/time/aboututc.html
[21]: https://man7.org/linux/man-pages/man1/date.1.html
[22]: https://help.gnome.org/users/zenity/stable/
[23]: https://github.com/Epholys/ultz
[24]: https://fedoramagazine.org/wp-content/uploads/2021/03/image-6-1024x407.png
[25]: https://github.com/KuenzelIT/ulauncher-firefox-bookmarks
[26]: https://fedoramagazine.org/wp-content/uploads/2021/03/image-3.png
[27]: https://github.com/friday/ulauncher-clipboard
[28]: https://github.com/Keruspe/GPaste
[29]: https://github.com/mrichar1/clipster
[30]: https://hluk.github.io/CopyQ/
[31]: https://fedoramagazine.org/wp-content/uploads/2021/03/image-4.png
[32]: https://github.com/NastuzziSamy/ulauncher-google-search
[33]: https://fedoramagazine.org/wp-content/uploads/2021/03/image-5.png

View File

@@ -1,91 +0,0 @@
[#]: subject: (Meet Sleek: A Sleek Looking To-Do List Application)
[#]: via: (https://itsfoss.com/sleek-todo-app/)
[#]: author: (Abhishek Prakash https://itsfoss.com/author/abhishek/)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
Meet Sleek: A Sleek Looking To-Do List Application
======
There are plenty of [to-do list applications available for Linux][1]. There is one more added to that list in the form of Sleek.
### Sleek to-do List app
Sleek is nothing extraordinary except for its looks perhaps. It provides an Electron-based GUI for todo.txt.
![][2]
For those not aware, [Electron][3] is a framework that lets you use JavaScript, HTML and CSS for building cross-platform desktop apps. It utilizes Chromium and Node.js for this purpose and this is why some people dont like their desktop apps running a browser underneath it.
[Todo.txt][4] is a text-based file system and if you follow its markup syntax, you can create a to-do list. There are tons of mobile, desktop and CLI apps that use Todo.txt underneath it.
Dont worry you dont need to know the correct syntax for todo.txt. Since Sleek is a GUI tool, you can utilize its interface for creating to-do lists without special efforts.
The advantage of todo.txt is that you can copy or export your files and use it on any To Do List app that supports todo.txt. This gives you portability to keep your data while moving between applications.
### Experience with Sleek
![][5]
Sleek gives you option to create a new to-do.txt or open an existing one. Once you create or open one, you can start adding items to the list.
Apart from the normal checklist, you can add tasks with due date.
![][6]
While adding a due date, you can also set the repetition for the tasks. I find this weird that you can not create a recurring task without setting a due date to it. This is something the developer should try to fix in the future release of the application.
![][7]
You can check a task complete. You can also choose to hide or show completed tasks with options to sort tasks based on priority.
Sleek is available in both dark and light theme. There is a dedicated option on the left sidebar to change themes. You can, of course, change it from the settings.
![][8]
There is no provision to sync your to-do list app. As a workaround, you can save your todo.txt file in a location that is automatically sync with Nextcloud, Dropbox or some other cloud service. This also opens the possibility of using it on mobile with some todo.txt mobile client. Its just a suggestion, I havent tried it myself.
### Installing Sleek on Linux
Since Sleek is an Electron-based application, it is available for Windows as well as Linux.
For Linux, you can install it using Snap or Flatpak, whichever you prefer.
For Snap, use the following command:
```
sudo snap install sleek
```
If you have enabled Flatpak and added Flathub repository, you can install it using this command:
```
flatpak install flathub com.github.ransome1.sleek
```
As I said at the beginning of this article, Sleek is nothing extraordinary. If you prefer a modern looking to-do list app with option to import and export your tasks list, you may give this open source application a try.
--------------------------------------------------------------------------------
via: https://itsfoss.com/sleek-todo-app/
作者:[Abhishek Prakash][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/abhishek/
[b]: https://github.com/lujun9972
[1]: https://itsfoss.com/to-do-list-apps-linux/
[2]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/03/sleek-to-do-list-app.png?resize=800%2C630&ssl=1
[3]: https://www.electronjs.org/
[4]: http://todotxt.org/
[5]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/03/sleek-to-do-list-app-1.png?resize=800%2C521&ssl=1
[6]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/03/sleek-to-do-list-app-due-tasks.png?resize=800%2C632&ssl=1
[7]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/03/sleek-to-do-list-app-repeat-tasks.png?resize=800%2C632&ssl=1
[8]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/03/sleek-to-do-list-app-light-theme.png?resize=800%2C521&ssl=1

View File

@@ -1,466 +0,0 @@
[#]: subject: (Build a to-do list app in React with hooks)
[#]: via: (https://opensource.com/article/21/3/react-app-hooks)
[#]: author: (Jaivardhan Kumar https://opensource.com/users/invinciblejai)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
Build a to-do list app in React with hooks
======
Learn to build React apps using functional components and state
management.
![Team checklist and to dos][1]
React is one of the most popular and simple JavaScript libraries for building user interfaces (UIs) because it allows you to create reusable UI components.
Components in React are independent, reusable pieces of code that serve as building blocks for an application. React functional components are JavaScript functions that separate the presentation layer from the business logic. According to the [React docs][2], a simple, functional component can be written like:
```
function Welcome(props) {
  return &lt;h1&gt;Hello, {props.name}&lt;/h1&gt;;
}
```
React functional components are stateless. Stateless components are declared as functions that have no state and return the same markup, given the same props. State is managed in components with hooks, which were introduced in React 16.8. They enable the management of state and the lifecycle of functional components. There are several built-in hooks, and you can also create custom hooks.
This article explains how to build a simple to-do app in React using functional components and state management. The complete code for this app is available on [GitHub][3] and [CodeSandbox][4]. When you're finished with this tutorial, the app will look like this:
![React to-do list][5]
(Jaivardhan Kumar, [CC BY-SA 4.0][6])
### Prerequisites
* To build locally, you must have [Node.js][7] v10.16 or higher, [yarn][8] v1.20.0 or higher, and npm 5.6
* Basic knowledge of JavaScript
* Basic understanding of React would be a plus
### Create a React app
[Create React App][9] is an environment that allows you to start building a React app. Along with this tutorial, I used a TypeScript template for adding static type definitions. [TypeScript][10] is an open source language that builds on JavaScript:
```
`npx create-react-app todo-app-context-api --template typescript`
```
[npx][11] is a package runner tool; alternatively, you can use [yarn][12]:
```
`yarn create react-app todo-app-context-api --template typescript`
```
After you execute this command, you can navigate to the directory and run the app:
```
cd todo-app-context-api
yarn start
```
You should see the starter app and the React logo which is generated by boilerplate code. Since you are building your own React app, you will be able to modify the logo and styles to meet your needs.
### Build the to-do app
The to-do app can:
* Add an item
* List items
* Mark items as completed
* Delete items
* Filter items based on status (e.g., completed, all, active)
![To-Do App architecture][13]
(Jaivardhan Kumar, [CC BY-SA 4.0][6])
#### The header component
Create a directory called **components** and add a file named **Header.tsx**:
```
mkdir components
cd  components
vi  Header.tsx
```
Header is a functional component that holds the heading:
```
const Header: React.FC = () =&gt; {
    return (
        &lt;div className="header"&gt;
            &lt;h1&gt;
                Add TODO List!!
            &lt;/h1&gt;
        &lt;/div&gt;
        )
}
```
#### The AddTodo component
The **AddTodo** component contains a text box and a button. Clicking the button adds an item to the list.
Create a directory called **todo** under the **components** directory and add a file named **AddTodo.tsx**:
```
mkdir todo
cd todo
vi AddTodo.tsx
```
AddTodo is a functional component that accepts props. Props allow one-way passing of data, i.e., only from parent to child components:
```
const AddTodo: React.FC&lt;AddTodoProps&gt; = ({ todoItem, updateTodoItem, addTaskToList }) =&gt; {
    const submitHandler = (event: SyntheticEvent) =&gt; {
        event.preventDefault();
        addTaskToList();
    }
    return (
        &lt;form className="addTodoContainer" onSubmit={submitHandler}&gt;
            &lt;div  className="controlContainer"&gt;
                &lt;input className="controlSpacing" style={{flex: 1}} type="text" value={todoItem?.text ?? ''} onChange={(ev) =&gt; updateTodoItem(ev.target.value)} placeholder="Enter task todo ..." /&gt;
                &lt;input className="controlSpacing" style={{flex: 1}} type="submit" value="submit" /&gt;
            &lt;/div&gt;
            &lt;div&gt;
                &lt;label&gt;
                    &lt;span style={{ color: '#ccc', padding: '20px' }}&gt;{todoItem?.text}&lt;/span&gt;
                &lt;/label&gt;
            &lt;/div&gt;
        &lt;/form&gt;
    )
}
```
You have created a functional React component called **AddTodo** that takes props provided by the parent function. This makes the component reusable. The props that need to be passed are:
* **todoItem:** An empty item state
* **updateToDoItem:** A helper function to send callbacks to the parent as the user types
* **addTaskToList:** A function to add an item to a to-do list
There are also some styling and HTML elements, like form, input, etc.
#### The TodoList component
The next component to create is the **TodoList**. It is responsible for listing the items in the to-do state and providing options to delete and mark items as complete.
**TodoList** will be a functional component:
```
const TodoList: React.FC = ({ listData, removeItem, toggleItemStatus }) =&gt; {
    return listData.length &gt; 0 ? (
        &lt;div className="todoListContainer"&gt;
            { listData.map((lData) =&gt; {
                return (
                    &lt;ul key={lData.id}&gt;
                        &lt;li&gt;
                            &lt;div className="listItemContainer"&gt;
                                &lt;input type="checkbox" style={{ padding: '10px', margin: '5px' }} onChange={() =&gt; toggleItemStatus(lData.id)} checked={lData.completed}/&gt;
                                &lt;span className="listItems" style={{ textDecoration: lData.completed ? 'line-through' : 'none', flex: 2 }}&gt;{lData.text}&lt;/span&gt;
                                &lt;button type="button" className="listItems" onClick={() =&gt; removeItem(lData.id)}&gt;Delete&lt;/button&gt;
                            &lt;/div&gt;
                        &lt;/li&gt;
                    &lt;/ul&gt;
                )
            })}
        &lt;/div&gt;
    ) : (&lt;span&gt; No Todo list exist &lt;/span &gt;)
}
```
The **TodoList** is also a reusable functional React component that accepts props from parent functions. The props that need to be passed are:
* **listData:** A list of to-do items with IDs, text, and completed properties
* **removeItem:** A helper function to delete an item from a to-do list
* **toggleItemStatus:** A function to toggle the task status from completed to not completed and vice versa
There are also some styling and HTML elements (like lists, input, etc.).
#### Footer component
**Footer** will be a functional component; create it in the **components** directory as follows:
```
cd ..
const Footer: React.FC = ({item = 0, storage, filterTodoList}) =&gt; {
    return (
        &lt;div className="footer"&gt;
            &lt;button type="button" style={{flex:1}} onClick={() =&gt; filterTodoList(ALL_FILTER)}&gt;All Item&lt;/button&gt;
            &lt;button type="button" style={{flex:1}} onClick={() =&gt; filterTodoList(ACTIVE_FILTER)}&gt;Active&lt;/button&gt;
            &lt;button type="button" style={{flex:1}} onClick={() =&gt; filterTodoList(COMPLETED_FILTER)}&gt;Completed&lt;/button&gt;
            &lt;span style={{color: '#cecece', flex:4, textAlign: 'center'}}&gt;{item} Items | Make use of {storage} to store data&lt;/span&gt;
        &lt;/div&gt;
    );
}
```
It accepts three props:
* **item:** Displays the number of items
* **storage:** Displays text
* **filterTodoList:** A function to filter tasks based on status (active, completed, all items)
### Todo component: Managing state with contextApi and useReducer
![Todo Component][14]
(Jaivardhan Kumar, [CC BY-SA 4.0][6])
Context provides a way to pass data through the component tree without having to pass props down manually at every level. **ContextApi** and **useReducer** can be used to manage state by sharing it across the entire React component tree without passing it as a prop to each component in the tree.
Now that you have the AddTodo, TodoList, and Footer components, you need to wire them.
Use the following built-in hooks to manage the components' state and lifecycle:
* **useState:** Returns the stateful value and updater function to update the state
* **useEffect:** Helps manage lifecycle in functional components and perform side effects
* **useContext:** Accepts a context object and returns current context value
* **useReducer:** Like useState, it returns the stateful value and updater function, but it is used instead of useState when you have complex state logic (e.g., multiple sub-values or if the new state depends on the previous one)
First, use **contextApi** and **useReducer** hooks to manage the state. For separation of concerns, add a new directory under **components** called **contextApiComponents**:
```
mkdir contextApiComponents
cd contextApiComponents
```
Create **TodoContextApi.tsx**:
```
const defaultTodoItem: TodoItemProp = { id: Date.now(), text: '', completed: false };
const TodoContextApi: React.FC = () =&gt; {
    const { state: { todoList }, dispatch } = React.useContext(TodoContext);
    const [todoItem, setTodoItem] = React.useState(defaultTodoItem);
    const [todoListData, setTodoListData] = React.useState(todoList);
    React.useEffect(() =&gt; {
        setTodoListData(todoList);
    }, [todoList])
    const updateTodoItem = (text: string) =&gt; {
        setTodoItem({
            id: Date.now(),
            text,
            completed: false
        })
    }
    const addTaskToList = () =&gt; {
        dispatch({
            type: ADD_TODO_ACTION,
            payload: todoItem
        });
        setTodoItem(defaultTodoItem);
    }
    const removeItem = (id: number) =&gt; {
        dispatch({
            type: REMOVE_TODO_ACTION,
            payload: { id }
        })
    }
    const toggleItemStatus = (id: number) =&gt; {
        dispatch({
            type: UPDATE_TODO_ACTION,
            payload: { id }
        })
    }
    const filterTodoList = (type: string) =&gt; {
        const filteredList = FilterReducer(todoList, {type});
        setTodoListData(filteredList)
    }
    return (
        &lt;&gt;
            &lt;AddTodo todoItem={todoItem} updateTodoItem={updateTodoItem} addTaskToList={addTaskToList} /&gt;
            &lt;TodoList listData={todoListData} removeItem={removeItem} toggleItemStatus={toggleItemStatus} /&gt;
            &lt;Footer item={todoListData.length} storage="Context API" filterTodoList={filterTodoList} /&gt;
        &lt;/&gt;
    )
}
```
This component includes the **AddTodo**, **TodoList**, and **Footer** components and their respective helper and callback functions.
To manage the state, it uses **contextApi**, which provides state and dispatch methods, which, in turn, updates the state. It accepts a context object. (You will create the provider for the context, called **contextProvider**, next).
```
` const { state: { todoList }, dispatch } = React.useContext(TodoContext);`
```
#### TodoProvider
Add **TodoProvider**, which creates **context** and uses a **useReducer** hook. The **useReducer** hook takes a reducer function along with the initial values and returns state and updater functions (dispatch).
* Create the context and export it. Exporting it will allow it to be used by any child component to get the current state using the hook **useContext**: [code]`export const TodoContext = React.createContext({} as TodoContextProps);`
```
* Create **ContextProvider** and export it: [code] const TodoProvider : React.FC = (props) =&gt; {
    const [state, dispatch] = React.useReducer(TodoReducer, {todoList: []});
    const value = {state, dispatch}
    return (
        &lt;TodoContext.Provider value={value}&gt;
            {props.children}
        &lt;/TodoContext.Provider&gt;
    )
}
```
* Context data can be accessed by any React component in the hierarchy directly with the **useContext** hook if you wrap the parent component (e.g., **TodoContextApi**) or the app itself with the provider (e.g., **TodoProvider**): [code] &lt;TodoProvider&gt;
  &lt;TodoContextApi /&gt;
&lt;/TodoProvider&gt;
```
* In the **TodoContextApi** component, use the **useContext** hook to access the current context value: [code]`const { state: { todoList }, dispatch } = React.useContext(TodoContext)`
```
**TodoProvider.tsx:**
```
type TodoContextProps = {
    state : {todoList: TodoItemProp[]};
    dispatch: ({type, payload}: {type:string, payload: any}) =&gt; void;
}
export const TodoContext = React.createContext({} as TodoContextProps);
const TodoProvider : React.FC = (props) =&gt; {
    const [state, dispatch] = React.useReducer(TodoReducer, {todoList: []});
    const value = {state, dispatch}
    return (
        &lt;TodoContext.Provider value={value}&gt;
            {props.children}
        &lt;/TodoContext.Provider&gt;
    )
}
```
#### Reducers
A reducer is a pure function with no side effects. This means that for the same input, the expected output will always be the same. This makes the reducer easier to test in isolation and helps manage state. **TodoReducer** and **FilterReducer** are used in the components **TodoProvider** and **TodoContextApi**.
Create a directory named **reducers** under **src** and create a file there named **TodoReducer.tsx**:
```
const TodoReducer = (state: StateProps = {todoList:[]}, action: ActionProps) =&gt; {
    switch(action.type) {
        case ADD_TODO_ACTION:
            return { todoList: [...state.todoList, action.payload]}
        case REMOVE_TODO_ACTION:
            return { todoList: state.todoList.length ? state.todoList.filter((d) =&gt; d.id !== action.payload.id) : []};
        case UPDATE_TODO_ACTION:
            return { todoList: state.todoList.length ? state.todoList.map((d) =&gt; {
                if(d.id === action.payload.id) d.completed = !d.completed;
                return d;
            }): []}
        default:
            return state;
    }
}
```
Create a **FilterReducer** to maintain the filter's state:
```
const FilterReducer =(state : TodoItemProp[] = [], action: ActionProps) =&gt; {
    switch(action.type) {
        case ALL_FILTER:
            return state;
        case ACTIVE_FILTER:
            return state.filter((d) =&gt; !d.completed);
        case COMPLETED_FILTER:
            return state.filter((d) =&gt; d.completed);
        default:
            return state;
    }
}
```
You have created all the required components. Next, you will add the **Header** and **TodoContextApi** components in App, and **TodoContextApi** with **TodoProvider** so that all children can access the context.
```
function App() {
  return (
    &lt;div className="App"&gt;
      &lt;Header /&gt;
      &lt;TodoProvider&gt;
              &lt;TodoContextApi /&gt;
      &lt;/TodoProvider&gt;
    &lt;/div&gt;
  );
}
```
Ensure the App component is in **index.tsx** within **ReactDom.render**. [ReactDom.render][15] takes two arguments: React Element and an ID of an HTML element. React Element gets rendered on a web page, and the **id** indicates which HTML element will be replaced by the React Element:
```
ReactDOM.render(
   &lt;App /&gt;,
  document.getElementById('root')
);
```
### Conclusion
You have learned how to build a functional app in React using hooks and state management. What will you do with it?
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/3/react-app-hooks
作者:[Jaivardhan Kumar][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/invinciblejai
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/todo_checklist_team_metrics_report.png?itok=oB5uQbzf (Team checklist and to dos)
[2]: https://reactjs.org/docs/components-and-props.html
[3]: https://github.com/invincibleJai/todo-app-context-api
[4]: https://codesandbox.io/s/reverent-edison-v8om5
[5]: https://opensource.com/sites/default/files/pictures/todocontextapi.gif (React to-do list)
[6]: https://creativecommons.org/licenses/by-sa/4.0/
[7]: https://nodejs.org/en/download/
[8]: https://yarnpkg.com/getting-started/install
[9]: https://github.com/facebook/create-react-app
[10]: https://www.typescriptlang.org/
[11]: https://www.npmjs.com/package/npx
[12]: https://yarnpkg.com/
[13]: https://opensource.com/sites/default/files/uploads/to-doapp_architecture.png (To-Do App architecture)
[14]: https://opensource.com/sites/default/files/uploads/todocomponent_0.png (Todo Component)
[15]: https://reactjs.org/docs/react-dom.html#render

View File

@@ -1,144 +0,0 @@
[#]: subject: (10 open source tools for content creators)
[#]: via: (https://opensource.com/article/21/3/open-source-tools-web-design)
[#]: author: (Kristina Tuvikene https://opensource.com/users/hfkristina)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
10 open source tools for content creators
======
Check out these lesser-known web design tools for your next project.
![Painting art on a computer screen][1]
There are a lot of well-known open source applications used in web design, but there are also many great tools that are not as popular. I thought I'd challenge myself to find some obscure options on the chance I might find something useful.
Open source offers a wealth of options, so it's no surprise that I found 10 new applications that I now consider indispensable to my work.
### Bulma
![Bulma widgets][2]
[Bulma][3] is a modular and responsive CSS framework for designing interfaces that flow beautifully. Design work is hardest between the moment of inspiration and the time of initial implementation, and that's exactly the problem Bulma helps solve. It's a collection of useful front-end components that a designer can combine to create an engaging and polished interface. And the best part is that it requires no JavaScript. It's all done in CSS.
Included components include forms, columns, tabbed interfaces, pagination, breadcrumbs, buttons, notifications, and much more.
### Skeleton
![Skeleton][4]
(Kristina Tuvikene, [CC BY-SA 4.0][5])
[Skeleton][6] is a lightweight open source framework that gives you a simple grid, basic formats, and cross-browser support. It's a great alternative for bulky frameworks and lets you start coding your site with a minimal but highly functional foundation. There's a slight learning curve, as you do have to get familiar with its codebase, but after you've built one site with Skeleton, you've built a thousand, and it becomes second-nature.
### The Noun Project
![The Noun Project][7]
(Kristina Tuvikene, [CC BY-SA 4.0][5])
[The Noun Project][8] is a collection of more than 3 million icons and images. You can use them on your site or as inspiration to create your own designs. I've found hundreds of useful icons on the site, and they're superbly easy to use. Because they're so basic, you can use them as-is for a nice, minimal look or bring them into your [favorite image editor][9] and customize them for your project.
### MyPaint
![MyPaint][10]
(Kristina Tuvikene, [CC BY-SA 4.0][5])
If you fancy creating your own icons or maybe some incidental art, then you should take a look at [MyPaint][11]. It is a lightweight painting tool that supports various graphic tablets, features dozens of amazing brush emulators and textures, and has a clean, minimal interface, so you can focus on creating your illustration.
### Glimpse
![Glimpse][12]
(Kristina Tuvikene, [CC BY-SA 4.0][5])
[Glimpse][13] is a cross-platform photo editor, a fork of [GIMP][14] that adds some nice features such as keyboard shortcuts similar to another popular (non-open) image editor. This is one of those must-have [applications for any graphic designer][15]. Climpse doesn't have a macOS release yet, but Mac users may use GIMP in the mean time.
### LazPaint
![LaPaz][16]
(Kristina Tuvikene, [CC BY-SA 4.0][5])
[LazPaint][17] is a lightweight raster and vector graphics editor with multiple tools and filters. It's also available on multiple platforms and offers straightforward vector editing for quick and basic work.
### The League of Moveable Type
![League of Moveable Type][18]
(Kristina Tuvikene, [CC BY-SA 4.0][5])
My favorite open source font foundry, [The League of Moveable Type][19], offers expertly designed open source font faces. There's something suitable for every sort of project here.
### Shotcut
![Shotcut][20]
(Kristina Tuvikene, [CC BY-SA 4.0][5])
[Shotcut][21] is a non-linear video editor that supports multiple audio and video formats. It has an intuitive interface, undockable panels, and you can do some basic to advanced video editing using this open source tool.
### Draw.io
![Draw.io][22]
(Kristina Tuvikene, [CC BY-SA 4.0][5])
[Draw.io][23] is lightweight, dedicated software with a straightforward user interface for creating professional diagrams and flowcharts. You can run it online or [get it from GitHub][24] and install it locally.
### Bonus resource: Olive video editor
![Olive][25]
(©2021, [Olive][26])
[Olive video editor][27] is a work in progress but considered a very strong contender for premium open source video editing software. It's something you should keep your eye on for sure.
### Add these to your collection
Web design is an exciting line of work, and there's always something unexpected to deal with or invent. There are many great open source options out there for the resourceful web designer, and you'll benefit from trying these out to see if they fit your style.
What open source web design tools do you use that I've missed? Please share your favorites in the comments!
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/3/open-source-tools-web-design
作者:[Kristina Tuvikene][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/hfkristina
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/painting_computer_screen_art_design_creative.png?itok=LVAeQx3_ (Painting art on a computer screen)
[2]: https://opensource.com/sites/default/files/bulma.jpg (Bulma widgets)
[3]: https://bulma.io/
[4]: https://opensource.com/sites/default/files/uploads/skeleton.jpg (Skeleton)
[5]: https://creativecommons.org/licenses/by-sa/4.0/
[6]: http://getskeleton.com/
[7]: https://opensource.com/sites/default/files/uploads/nounproject.jpg (The Noun Project)
[8]: https://thenounproject.com/
[9]: https://opensource.com/life/12/6/design-without-debt-five-tools-for-designers
[10]: https://opensource.com/sites/default/files/uploads/mypaint.jpg (MyPaint)
[11]: http://mypaint.org/
[12]: https://opensource.com/sites/default/files/uploads/glimpse.jpg (Glimpse)
[13]: https://glimpse-editor.github.io/
[14]: https://www.gimp.org/
[15]: https://websitesetup.org/web-design-software/
[16]: https://opensource.com/sites/default/files/uploads/lapaz.jpg (LaPaz)
[17]: https://lazpaint.github.io/
[18]: https://opensource.com/sites/default/files/uploads/league-of-moveable-type.jpg (League of Moveable Type)
[19]: https://www.theleagueofmoveabletype.com/
[20]: https://opensource.com/sites/default/files/uploads/shotcut.jpg (Shotcut)
[21]: https://shotcut.org/
[22]: https://opensource.com/sites/default/files/uploads/drawio.jpg (Draw.io)
[23]: http://www.draw.io/
[24]: https://github.com/jgraph/drawio
[25]: https://opensource.com/sites/default/files/uploads/olive.png (Olive)
[26]: https://olivevideoeditor.org/020.php
[27]: https://olivevideoeditor.org/

View File

@@ -1,108 +0,0 @@
[#]: subject: (Network address translation part 3 the conntrack event framework)
[#]: via: (https://fedoramagazine.org/conntrack-event-framework/)
[#]: author: (Florian Westphal https://fedoramagazine.org/author/strlen/)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
Network address translation part 3 the conntrack event framework
======
![][1]
This is the third post in a series about network address translation (NAT). The first article introduced [how to use the iptables/nftables packet tracing feature][2] to find the source of NAT-related connectivity problems. Part 2 [introduced the “conntrack” command][3]. This part gives an introduction to the “conntrack” event framework.
### Introduction
NAT configured via iptables or nftables builds on top of netfilters connection tracking framework. conntracks event facility allows real-time monitoring of incoming and outgoing flows. This event framework is useful for debugging or logging flow information, for instance with [ulog][4] and its IPFIX output plugin.
### Conntrack events
Run the following command to see a real-time conntrack event log:
```
# conntrack -E
NEW tcp 120 SYN_SENT src=10.1.0.114 dst=10.7.43.52 sport=4123 dport=22 [UNREPLIED] src=10.7.43.52 dst=10.1.0.114 sport=22 dport=4123
UPDATE tcp 60 SYN_RECV src=10.1.0.114 dst=10.7.43.52 sport=4123 dport=22 src=10.7.43.52 dst=10.1.0.114 sport=22 dport=4123
UPDATE tcp 432000 ESTABLISHED src=10.1.0.114 dst=10.7.43.52 sport=4123 dport=22 src=10.7.43.52 dst=10.1.0.114 sport=22 dport=4123 [ASSURED]
UPDATE tcp 120 FIN_WAIT src=10.1.0.114 dst=10.7.43.52 sport=4123 dport=22 src=10.7.43.52 dst=10.1.0.114 sport=22 dport=4123 [ASSURED]
UPDATE tcp 30 LAST_ACK src=10.1.0.114 dst=10.7.43.52 sport=4123 dport=22 src=10.7.43.52 dst=10.1.0.114 sport=22 dport=4123 [ASSURED]
UPDATE tcp 120 TIME_WAIT src=10.1.0.114 dst=10.7.43.52 sport=4123 dport=22 src=10.7.43.52 dst=10.1.0.114 sport=22 dport=4123 [ASSURED]
```
This prints a continuous stream of events:
* new connections
* removal of connections
* changes in a connections state.
Hit _ctrl+c_ to quit.
The conntrack tool offers a number of options to limit the output. For example its possible to only show DESTROY events. The NEW event is generated after the iptables/nftables rule set accepts the corresponding packet.
### **Conntrack expectations**
Some legacy protocols require multiple connections to work, such as [FTP][5], [SIP][6] or [H.323][7]. To make these work in NAT environments, conntrack uses “connection tracking helpers”: kernel modules that can parse the specific higher-level protocol such as ftp.
The _nf_conntrack_ftp_ module parses the ftp command connection and extracts the TCP port number that will be used for the file transfer. The helper module then inserts a “expectation” that consists of the extracted port number and address of the ftp client. When a new data connection arrives, conntrack searches the expectation table for a match. An incoming connection that matches such an entry is flagged RELATED rather than NEW. This allows you to craft iptables and nftables rulesets that reject incoming connection requests unless they were requested by an existing connection. If the original connection is subject to NAT, the related data connection will inherit this as well. This means that helpers can expose ports on internal hosts that are otherwise unreachable from the wider internet. The next section will explain this expectation mechanism in more detail.
### The expectation table
Use _conntrack -L expect_ to list all active expectations. In most cases this table appears to be empty, even if a helper module is active. This is because expectation table entries are short-lived. Use _conntrack -E expect_ to monitor the system for changes in the expectation table instead.
Use this to determine if a helper is working as intended or to log conntrack actions taken by the helper. Here is an example output of a file download via ftp:
```
```
# conntrack -E expect
NEW 300 proto=6 src=10.2.1.1 dst=10.8.4.12 sport=0 dport=46767 mask-src=255.255.255.255 mask-dst=255.255.255.255 sport=0 dport=65535 master-src=10.2.1.1 master-dst=10.8.4.12 sport=34526 dport=21 class=0 helper=ftp
DESTROY 299 proto=6 src=10.2.1.1 dst=10.8.4.12 sport=0 dport=46767 mask-src=255.255.255.255 mask-dst=255.255.255.255 sport=0 dport=65535 master-src=10.2.1.1 master-dst=10.8.4.12 sport=34526 dport=21 class=0 helper=ftp
```
```
The expectation entry describes the criteria that an incoming connection request must meet in order to recognized as a RELATED connection. In this example, the connection may come from any port, must go to port 46767 (the port the ftp server expects to receive the DATA connection request on). Futhermore the source and destination addresses must match the address of the ftp client and server.
Events also include the connection that created the expectation and the name of the protocol helper (ftp). The helper has full control over the expectation: it can request full matching (IP addresses of the incoming connection must match), it can restrict to a subnet or even allow the request to come from any address. Check the “mask-dst” and “mask-src” parameters to see what parts of the addresses need to match.
### Caveats
You can configure some helpers to allow wildcard expectations. Such wildcard expectations result in requests coming from an unrelated 3rd party host to get flagged as RELATED. This can open internal servers to the wider internet (“NAT slipstreaming”).
This is the reason helper modules require explicit configuration from the nftables/iptables ruleset. See [this article][8] for more information about helpers and how to configure them. It includes a table that describes the various helpers and the types of expectations (such as wildcard forwarding) they can create. The nftables wiki has a [nft ftp example][9].
A nftables rule like ct state related ct helper “ftp” matches connections that were detected as a result of an expectation created by the ftp helper.
In iptables, use “_-m conntrack ctstate RELATED -m helper helper ftp_“. Always restrict helpers to only allow communication to and from the expected server addresses. This prevents accidental exposure of other, unrelated hosts.
### Summary
This article introduced the conntrack event facilty and gave examples on how to inspect the expectation table. The next part of the series will describe low-level debug knobs of conntrack.
--------------------------------------------------------------------------------
via: https://fedoramagazine.org/conntrack-event-framework/
作者:[Florian Westphal][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://fedoramagazine.org/author/strlen/
[b]: https://github.com/lujun9972
[1]: https://fedoramagazine.org/wp-content/uploads/2021/03/network-address-translation-part-3-816x345.jpg
[2]: https://fedoramagazine.org/network-address-translation-part-1-packet-tracing/
[3]: https://fedoramagazine.org/network-address-translation-part-2-the-conntrack-tool/
[4]: https://netfilter.org/projects/ulogd/index.html
[5]: https://en.wikipedia.org/wiki/File_Transfer_Protocol
[6]: https://en.wikipedia.org/wiki/Session_Initiation_Protocol
[7]: https://en.wikipedia.org/wiki/H.323
[8]: https://github.com/regit/secure-conntrack-helpers/blob/master/secure-conntrack-helpers.rst
[9]: https://wiki.nftables.org/wiki-nftables/index.php/Conntrack_helpers

View File

@@ -1,129 +0,0 @@
[#]: subject: (My favorite open source tools to meet new friends)
[#]: via: (https://opensource.com/article/21/3/open-source-streaming)
[#]: author: (Chris Collins https://opensource.com/users/clcollins)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
My favorite open source tools to meet new friends
======
Quarantine hasn't been all bad—it's allowed people to create fun online
communities that also help others.
![Two people chatting via a video conference app][1]
In March 2020, I joined the rest of the world in quarantine at home for two weeks. Then, two weeks turned into more. And more. It wasn't too hard on me at first. I had been working a remote job for a year already, and I'm sort of an introvert in some ways. Being at home was sort of "business as usual" for me, but I watched as it took its toll on others, including my wife.
### An unlikely lifeline
That spring, I found out a buddy and co-worker of mine was a Fairly Well-Known Streamer™ who had been doing a podcast for something ridiculous, like _15 years_. So, I popped into the podcast's Twitch channel, [2DorksTV][2]. What I found, I was not prepared for. My friend and his co-hosts perform their podcast _live_ on Twitch, like the cast of _Saturday Night Live_ or something! _**Live!**_ The hosts, Stephen, Ashley, and Jacob, joked and laughed, (sometimes) read news stories, and interacted with a vibrant community of followers—_live!_
I introduced myself in the chat, and Stephen looked into the camera and welcomed me, as though he were looking at and talking directly to me. I was surprised to find that there was a real back and forth. The community in the chat talked with the hosts and one another, and the hosts interacted with the chat.
It was a great time, and I laughed out loud for the first time in several months.
### Trying a new thing
Shortly after getting involved in the community, I thought I might try out streaming for myself. I didn't have a podcast or a co-host, but I really, _really_ like to play Dwarf Fortress, a video game that's not open source but is built for Linux. People stream themselves playing games, right? I had all the stuff I needed because I already worked remotely full time. Other folks were struggling to find a webcam in stock and a spot to work that wasn't a kitchen table, but I'd been set up for months.
When I looked into it more, I found that a free and open source video recording and streaming application named OBS Studio is one of the most popular ways to stream to Twitch and other platforms. Score one for open source!
[OBS worked][3] _right out of the box_ on my Fedora system, so there's not much to write about. And that's a good thing!
So, it wasn't because of the software that my first stream was…rough, to say the least. I didn't really know what I was doing, the quality wasn't that great, and I kept muting the mic to cough and forgetting to turn it back on. I think there were a grand total of zero viewers who saw that stream, and that's probably for the best.
The next day though, I shared what I'd done in chat, and everyone was amazingly supportive. I decided to try again. In the second stream, Stephen popped in and said hi, and I had the opportunity to be on the other side of the camera, talking to a friend in chat and really enjoying the interaction. Within a few more streams, more of the community started to hop on and chat and hang out and, despite having no idea what was going on (Dwarf Fortress is famously a bit dense), sticking around and interacting with me.
### The open source behind the stream
Eventually, I started to up my game. Not my Dwarf Fortress game, but my streaming game. My stream slowly became more polished and more frequent. I created my own official stream, called _It's Dwarf Fortress! …with Hammerdwarf!_
The entire production is powered by open source:
* [VLC Media Player][4] plays the intro and outro music.
* I use [GIMP][5] (GNU Image Manipulation Program) to make the logos and splash screens.
* [OBS Studio][6] handles the recording and streaming.
* Both GIMP and OBS are packaged with [Flatpak][7], a seriously cool next-generation packaging technology for Linux.
* I've recently started using [OpenShot][8] to edit recordings of my stream before uploading them to YouTube.
* Even the fonts I use are Open Font License fonts.
* All this, the game included, live on a Fedora Linux system.
### Coding out in the open
As I got further into streaming, I discovered, again through Stephen, that folks stream themselves programming. What?! But it's oddly satisfying, listening to someone calmly talk about what they're doing and why and hearing the quiet clicks of their keyboard. I've started keeping those kinds of things on in the background while I work, just for ambiance.
Eventually, I thought to myself, "Why not? I could do that too. I program things." I had plenty of side projects to work on, and maybe folks would come hang out with me while I work on them.
I created a new stream called _It's _not_ Dwarf Fortress! …with Hammerdwarf!_ (Look—that's just how Dwarf Fortress-y I am.) I started up that stream and worked on a little side project, and—the very first time—a group of four or five folks from my previous job hopped in and hung out with me, despite it being the middle of their workday. Friends from the 2DorksTV Discord joined as well, and we had a nice big group of folks chatting and helping me troubleshoot code and regexes and missing whitespace. And then, some random folks I didn't know, folks looking around for a stream on Twitch, found it and jumped in as well!
### Sharing is what open source is about
Fast forward a few months, and I was talking (again) with Stephen. Over the months, we've discussed how folks represent themselves online and commiserated about feeling out of place at work, fighting to feel like we deserve to be there, to convince ourselves that we're good enough to be there. It's not just him or just me, I realize. I have this conversation with _so many people_. I told Stephen that I think it's because there is so little representation of _trying_. Everyone shares their success story on Twitter. They only ever _do_ or _don't_.
They never share themselves trying.
("Friggin Yoda, man," Stephen commented on the matter. You can see why he's got a successful podcast.)
Presentations at tech conferences are filled with complicated, difficult stories, but they're always success stories. The "internet famous" in our field, developer advocates and tech gurus, share amazing new things and present complicated demos, but all of them are backed by teams of people working with them that no one ever sees. Online, with tech specifically and honestly the rest of the world generally, you see only the finished sausage, not all the grind.
These are the things I think help people, and I realized that I need to be open about all of my processes. Projects I work on take me _forever_ to figure out. Code that I write _sucks_. I'm a senior software engineer/site reliability engineer for a large software company. I spend _hours and hours_ reading documentation, struggling to figure out how something works, and slowly, slowly incrementing on it. Even that first Dwarf Fortress stream needed a lot of help.
And this is normal!
Everyone does it, but we're so tuned into sharing our successes and hiding our failures that all we can compare our flawed selves to is other people's successes. We never see their failures, and we try to live up to a standard of illusion.
I even struggled to decide whether I should create a whole new channel for this thing I was trying to do. I spent all this time building a professional career image online—I couldn't show everyone how much of a Dwarf Dork I _really_ am! And once again, Stephen inspired me:
> "Hammerdwarf is you. And your coding stream was definitely a professional stream. The channel name didn't matter…Be authentic."
Professional Chris Collins and personal Hammerdwarf make up who I am. I have a wife and two dogs, I like space stuff, I get a headache every now and again, I write for Opensource.com and [EnableSysadmin][9], I speak at tech conferences, and sometimes, I have to take an afternoon off work to sit in the sun or lie awake at night because I miss my friends.
All that to say, my summer project, inspired by Stephen, Ashley, and Jacob and the community from 2DorksTV and powered by open source technology, is to fail publicly and to be real. To borrow a phrase from another excellent podcast: I am [failing out loud][10].
I've started a streaming program on Twitch called _Practically Programming_, dedicated to showing what it is like for me at work, working on real things and failing and struggling and needing help. I've been in tech for almost 20 years, and I still have to learn every day, and now I'm going to do so online where everyone can see me. Because it's important to show your failures and flaws as much as your successes, and it's important to see others fail and realize it's a normal part of life.
![Practically Programming logo][11]
(Chris Collins, [CC BY-SA 4.0][12])
That's what I did last summer.
And _Practically Programming_ is what I will be doing this spring and from now on. Please join me if you're interested, and please, if you fail at something or struggle with something, know that everyone else is doing so, too. As long as you keep trying and keep learning, it doesn't matter how many times you fail.
You got this!
* * *
_Practically Programming_ is on my [Hammerdwarf Twitch channel][13] on Tuesdays and Thursdays at 5pm Pacific time.
Dwarf Fortress is on almost any other time…
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/3/open-source-streaming
作者:[Chris Collins][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/clcollins
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/chat_video_conference_talk_team.png?itok=t2_7fEH0 (Two people chatting via a video conference app)
[2]: https://www.twitch.com/2dorkstv
[3]: https://opensource.com/article/20/4/open-source-live-stream
[4]: https://www.videolan.org/vlc/index.html
[5]: https://www.gimp.org/
[6]: https://obsproject.com/
[7]: https://opensource.com/article/21/2/linux-packaging
[8]: https://opensource.com/article/21/2/linux-python-video
[9]: http://redhat.com/sysadmin
[10]: https://open.spotify.com/show/1WcfOvSiD99zrVLFWlFHpo
[11]: https://opensource.com/sites/default/files/uploads/practically_programming_logo.png (Practically Programming logo)
[12]: https://creativecommons.org/licenses/by-sa/4.0/
[13]: https://www.twitch.tv/hammerdwarf

View File

@@ -1,226 +0,0 @@
[#]: subject: (Rapidly configure SD cards for your Raspberry Pi cluster)
[#]: via: (https://opensource.com/article/21/3/raspberry-pi-cluster)
[#]: author: (Gregor von Laszewski https://opensource.com/users/laszewski)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
Rapidly configure SD cards for your Raspberry Pi cluster
======
Create multiple SD cards that are preconfigured to create Pi clusters
with Cloudmesh Pi Burner.
![Raspberries with pi symbol overlay][1]
There are many reasons people want to create [computer clusters][2] using the Raspberry Pi, including that they have full control over their platform, they're able to use an inexpensive, highly usable platform, and get the opportunity to learn about cluster computing in general.
There are different methods for setting up a cluster, such as headless, network booting, and booting from SD cards. Each method has advantages and disadvantages, but the latter method is most familiar to users who have worked with a single Pi. Most cluster setups involve many complex steps that require a significant amount of time because they are executed on an individual Pi. Even starting is non-trivial, as you need to set up a network to access them.
Despite improvements to the [Raspberry Pi Imager][3] and the availability of [PiBakery][4], the process is still too involved. So, at Cloudmesh, we asked:
> Is it possible to develop a tool that is specifically targeted to burn SD cards for Pis in a cluster one at a time so that the cards can be just plugged in and, with minimal effort, start a cluster that simply works?
In response, we developed a tool called **Cloudmesh Pi Burner** for SD Cards, and we present it within [Pi Planet][5]. No more spending hours upon hours to replicate the steps and learn complex DevOps tutorials; instead, you can get a cluster set up with just a few commands.
For this, we developed `cms burn`, which is a program that you can execute on a "manager" Pi or a Linux or macOS computer to burn cards for your cluster.
We set up a [comprehensive package][6] on GitHub that can be installed easily. You can read about it in detail in the [README][7]. There, you can also find detailed instructions on how to [burn directly][8] from a macOS or Linux computer.
### Getting started
This article explains how to create a cluster setup using five Raspberry Pi units (you need a minimum of two, but this method also works for larger numbers). To follow along, you must have five SD cards, one for each of the five Pi units. It's helpful to have a network switch (managed or unmanaged) with five Ethernet cables (one for each Pi).
#### Requirements
You need:
* 5 Raspberry Pi boards
* 5 SD cards
* 5 Ethernet cables
* A network switch (unmanaged or managed)
* WiFi access
* Monitor, mouse, keyboard (for desktop access on Pi)
* An SD card slot for your computer or the manager Pi (and preferably supports USB 3.0 speeds)
* If you're doing this on a Mac, you must install [XCode][9] and [Homebrew][10]
On Linux, the open source **ext4** filesystem is supported by default. However, Apple doesn't provide this capability for macOS, so you must purchase support separately. I use Paragon Software's **extFS** application. Like macOS itself, this is largely based upon, but is not itself, open source.
At Cloudmesh, we maintain a list of [hardware parts][11] you need to consider when setting up a cluster.
### Network configuration
Figure 1 shows our network configuration. Of the five Raspberry Pi computers, one is dedicated as a _manager_ and four are _workers_. Using WiFi for the manager Pi allows you to set it up anywhere in your house or other location (other configurations are discussed in the README).
Our configuration uses an unmanaged network switch, where the manager and workers communicate locally with each other, and the manager provides internet access to the workers over a bridge that's configured for you.
![Pi cluster setup with bridge network][12]
Pi cluster setup with bridge network (©2021 [The Cloudmesh Projects][13])
### Set up the Cloudmesh burn application
To set up the Cloudmesh burn program, first [create a Python `venv`][14]:
```
$ python3 -m venv ~/ENV3
$ source ~/ENV3/bin/activate
```
Next, install the Cloudmesh cluster generation tools and start the burn process. You must adjust the path to your SD card, which differs depending on your system and what kind of SD card reader you're using. Here's an example:
```
(ENV3)$ pip install cloudmesh-pi-cluster
(ENV3)$ cms help
(ENV3)$ cms burn info
(ENV3)$ cms burn cluster \
\--device=/path/to/sdcard \
\--hostname=red,red01,red02,red03,red04 \
\--ssid=myssid -y
```
Fill out the passwords and plug in the SD cards as requested.
### Start your cluster and configure it
Plug the burned SD cards into the Pis and switch them on. Execute the `ssh` command to log into your manager—it's the one called `red` (worker nodes are identified by number):
```
`(ENV3)$ ssh pi@red.local`
```
This takes a while, as the filesystems on the SD cards need to be installed, and configurations such as Country, SSH, and WiFi need to be activated.
Once you are in the manager, install the Cloudmesh cluster software in it. (You could have done this automatically, but we decided to leave this part of the process up to you to give you maximum flexibility.)
```
pi@red:~ $ curl -Ls \
<http://cloudmesh.github.io/get/pi> \
\--output install.sh
pi@red:~ $ sh ./install.sh
```
After lots of log messages, you see:
```
#################################################
# Install Completed                             #
#################################################
Time to update and upgarde: 339 s
Time to install the venv:   22 s
Time to install cloudmesh:  185 s
Time for total install:     546 s
Time to install: 546 s
#################################################
Please activate with
    source ~/ENV3/bin/activate
```
Reboot:
```
`pi@red:~ $ sudo reboot`
```
### Start using your cluster
Log in to your manager Pi over SSH:
```
`(ENV3)$ ssh pi@red.local`
```
Once you're logged into your manager (in this example, `red.local`) on the network, execute a command to see if things are working. For example, you can use a temperature monitor to get the temperature from all Pi boards:
```
(ENV3) pi@red:~ $ cms pi temp red01,red02,red03,red04
pi temp red01,red02
+--------+--------+-------+----------------------------+
| host   |    cpu |   gpu | date                       |
|--------+--------+-------+----------------------------|
| red01  | 45.277 |  45.2 | 2021-02-23 22:13:11.788430 |
| red02  | 42.842 |  42.8 | 2021-02-23 22:13:11.941566 |
| red02  | 43.356 |  42.8 | 2021-02-23 22:13:11.961245 |
| red02  | 44.124 |  42.8 | 2021-02-23 22:13:11.981896 |
+--------+--------+-------+----------------------------+
```
### Access the workers
It's even more convenient to access the workers, so we designed a tunnel command that makes setup easy. Call it on the manager node, for example:
```
`(ENV3) pi@red:~ $ cms host setup "red0[1-4]" user@laptop.local`
```
This creates ssh keys on all workers, gathers ssh keys from all hosts, and scatters the public keys to the manager's and worker's authorized key file. This also makes the manager node a bridge for the worker nodes so they can have internet access. Now our laptop we update our ssh config file with the following command.
```
`(ENV3)$ cms host config proxy pi@red.local red0[1-4]`
```
Now you can access the workers from your computer. Try it out with the temperature program:
```
(ENV3)$ cms pi temp "red,red0[1-4]"              
+-------+--------+-------+----------------------------+
| host  |    cpu |   gpu | date                       |
|-------+--------+-------+----------------------------|
| red   | 50.147 |  50.1 | 2021-02-18 21:10:05.942494 |
| red01 | 51.608 |  51.6 | 2021-02-18 21:10:06.153189 |
| red02 | 45.764 |  45.7 | 2021-02-18 21:10:06.163067 |
...
+-------+--------+-------+----------------------------+
```
### More information
Since this uses SSH keys to authenticate between the manager and the workers, you can log directly into the workers from the manager. You can find more details in the [README][7] and on [Pi Planet][5]. Other Cloudmesh components are discussed in the [Cloudmesh manual][15].
* * *
_This article is based on [Easy Raspberry Pi cluster setup with Cloudmesh from MacOS][13] and is republished with permission._
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/3/raspberry-pi-cluster
作者:[Gregor von Laszewski][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/laszewski
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/life-raspberrypi_0.png?itok=Kczz87J2 (Raspberries with pi symbol overlay)
[2]: https://en.wikipedia.org/wiki/Computer_cluster
[3]: https://www.youtube.com/watch?v=J024soVgEeM
[4]: https://www.raspberrypi.org/blog/pibakery/
[5]: https://piplanet.org/
[6]: https://github.com/cloudmesh/cloudmesh-pi-burn
[7]: https://github.com/cloudmesh/cloudmesh-pi-burn/blob/main/README.md
[8]: https://github.com/cloudmesh/cloudmesh-pi-burn#71-quickstart-for-a-setup-of-a-cluster-from-macos-or-linux-with-no-burning-on-a-pi
[9]: https://opensource.com/article/20/8/iterm2-zsh
[10]: https://opensource.com/article/20/6/homebrew-mac
[11]: https://cloudmesh.github.io/pi/docs/hardware/parts/
[12]: https://opensource.com/sites/default/files/uploads/network-bridge.png (Pi cluster setup with bridge network)
[13]: https://cloudmesh.github.io/pi/tutorial/sdcard-burn-pi-headless/
[14]: https://opensource.com/article/20/10/venv-python
[15]: https://cloudmesh.github.io/cloudmesh-manual/

View File

@@ -1,500 +0,0 @@
[#]: subject: (Setting up a VM on Fedora Server using Cloud Images and virt-install version 3)
[#]: via: (https://fedoramagazine.org/setting-up-a-vm-on-fedora-server-using-cloud-images-and-virt-install-version-3/)
[#]: author: (pboy https://fedoramagazine.org/author/pboy/)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
Setting up a VM on Fedora Server using Cloud Images and virt-install version 3
======
![][1]
Photo by [Max Kukurudziak][2] on [Unsplash][3]
Many servers use one or more virtual machines (VMs), e.g. to isolate a public service in the best possible way and to protect the host server from compromise. This article explores the possibilities of deploying [Fedora Cloud Base][4] images as a VM in an autonomous Fedora 33 Server Edition using version 3 of _virt-install_. This capability was introduced with Fedora 33 and the new _-cloud-init_ option.
### Why use Cloud Images?
The standard virtualization tool for Fedora Server is _libvirt_. For a long time the only way to create a virtual Fedora Server instance was to create a _libvirt_ VM and run the standard Anaconda installation. Several tools exist to make this procedure as comfortable and fail-safe as possible, e.g. a [Cockpit module][5]. The process is pretty straight forward and every Fedora system administrator is used to it.
With the advent of cloud systems came cloud images. These are pre-built ready-to-run virtual servers. Fedora provides specialized images for various cloud systems as well as Fedora Cloud Base image, a generic optimized VM. The image image is copied to the server and used by a virtual machine as an operational file system.
These images save the system administrator the time-consuming process of many individual passes through Anaconda. An installation merely requires the invocation of _virt-install_ with suitable parameters. It is a CLI tool, thus easily scriptable and reproducible. In a worst case emergency, a replacement VM can be set up quickly.
Fedora Cloud Base images are integrated into the Fedora QA Process. This prevents subtle inconsistencies that may lead to not-so-subtle problems during operation. For any system administrator concerned about security and reliability, this is an incredibly valuable advantage over _libvirt_ compatible VM images from third party vendors. Cloud images speed up the deployment process as well.
#### Implementation considerations
As usual, there is nothing for free. Cloud images use _cloud-init_ for an automatic initial configuration, which is otherwise done as part of Anaconda. The cloud system usually provides the necessary information. In the absence of cloud, the system administrator must provide a replacement.
Basically, there are two implementation options.
First, with relatively little additional effort, you can install [Vagrant and the Vagrant libvirt plugin][6]. If the server is also used for development work, Vagrant may already be in use and the additional effort is minimal. This option is then the optimal choice.
Second, you can use _virt-install_ directly. Until now you had to create a cloud-init nocloud datasource iso in [several additional steps][7]. v_irt-install_ version 3, included since Fedora 33, elements these additional steps. The newly introduced _-cloud-init_ option initially configures a VM from a cloud image without additional software and without detours. _Virt-install_ takes on taming the rather complex cloud-init nocloud procedures.
There are two ways to make use of _virt-install_:
* quick and (not really) dirty: minimal Cloud-init configuration
This requires a little more post-installation effort and is suitable if you set up only a few VMs.
* elaborate cloud-init based configuration using simple configuration files
This requires more pre-installation work and is more effective if you have to set up multiple VMs.
#### Be certain you know what you are getting
There is no light without shadow. Cloud Base image (currently) do not provide an alternatively built but otherwise identical build of Fedora Server Edition. There are some subtle differences. For example:
* Fedora Server Edition uses xfs as its file system, Cloud Base Image still uses the older ext4.
* Fedora Server Edition now persists the network configuration completely and stringently in NetworkManager, Fedora Cloud Base image still uses the old ifcfg plugin.
* Other differences are conceptual. For example, Fedora Cloud image does not install a firewall by default.
* The use concept for the persistent storage is also different due to technical differences.
Overall, however, the functionality is so far identical and the advantages so noticeable that it is worthwhile and makes sense to use Fedora Cloud Base.
### A **t**ypical **u**se **c**ase
Consider a use case that often applies to small and medium-sized organizations. The hardware is located in an off-premise housing center. Fedora Server is required with the most rigorous isolation possible from public access, e.g. ssh and key based authentication only. Any risk of compromise has to be minimized. Public services are offered in a VM to provide as much isolation as possible. The VM operates as a pure front end with minimal exposure of services. For example, only an Apache web server is installed. All data processing resides on an application server in a separate VM (or a container), e.g. JBoss rsp. Wildfly. The application server accesses a database that may run directly on the host hardware for performance reasons but without any public access.
Regarding the infrastructure, at least some VMs as well as the host ssh or vpn process need access to the public network. They have to share the physical interface. At the same time, VMs and host need another internal network that enables protected communication. The application VM only connects to the internal network. And we need an internal DNS for the services to find each other.
### **System Requirements**
You need a Fedora 33 Server Edition with _libvirt_ virtualization properly installed and working. The _libvirt_ network “default” with virbr0 provides the internal protected network and is active. Some external network device, usually a router, provides DHCP service for the external network. Every lab or production environment should meet these requirements.
For internal name resolution to work, you have to decide upon an internal domain name and extend the _libvirt_ network configuration. In this example the external name will be _example.com_, and the internal domain name will be _example.lan_. The Fedora server thus receives the name _host.example.com_ externally and internally _host.example.lan_ or just _host_ for short. The names of the VMs are _**app**_ and _**web**_, respectively. The two examples that follow will create these VMs.
#### Network preparations for the examples
Modify the configuration of the internal network similar to the example below (N.B. adjust your domain name accordingly! Leave mac address and UUID untouched!):
```
# virsh net-edit default
<network>
<name>default</name>
<uuid>aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee</uuid>
<bridge name='virbr0' stp='on' delay='0'/>
<mac address='52:54:00:xx:yy:zz'/>
<forward mode='nat'/>
<mtu size='8000'/>
<domain name='example.lan'/>
<dns forwardPlainNames='no'>
<forwarder domain='example.lan' />
<host ip='192.168.122.1'>
<hostname>host</hostname>
<hostname>host.example.lan</hostname>
</host>
</dns>
<ip address='192.168.122.1' netmask='255.255.255.0'>
<dhcp>
<range start='192.168.122.2' end='192.168.122.200'/>
</dhcp>
</ip>
</network>
# virsh net-destroy default
# virsh net-start default
```
Do NOT add an external forwarder via _&lt;forwarder addr=xxx.yyy.zz.uu/&gt;_ tag. It will break the VMs split-dns capability.
Due to a bug in the interaction of _systemd-resolved_ and _libvirt_, the name resolution for the internal network does not work on the host at the moment without additional measures. The VMs are not affected. Hence, the host cannot resolve the names of the VMs, but conversely, the VMs can resolve to each other and to the host. The latter is sufficient here.
With everything set up correctly the following interfaces are active on the host:
```
# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu ...
inet 127.0.0.1/8 scope host ...
inet6 ::1/128 scope host ...
2: enpNsM: <BROADCAST,MULTICAST, ...
inet xxx.yyy.zzz.uuu/24 brd xxx. ...
inet6 200x:xx:yyy:...
inet6 fe80::xxx:yyy:...
3: virbr0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu ...
inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
...
4: virbr0-nic: <BROADCAST,MULTICAST> mtu 8...
```
### Creating a Fedora Server **v**irtual **m**achine **u**sing Fedora Cloud Base Image
#### Preparations
First download a Fedora 33 Cloud Base Image file and store it in the directory _/var/lib/libvirt/boot_. By convention, this is the location from which images are installed.
```
# sudo wget https://download.fedoraproject.org/pub/fedora/linux/releases/33/Cloud/x86_64/images/Fedora-Cloud-Base-33-1.2.x86_64.qcow2 -O /var/lib/libvirt/boot/Fedora-Cloud-Base-33-1.2.x86_64.qcow2
# sudo wget https://getfedora.org/static/checksums/Fedora-Cloud-33-1.2-x86_64-CHECKSUM -O /var/lib/libvirt/boot/Fedora-Cloud-33-1.2-x86_64-CHECKSUM
# sudo cd /var/lib/libvirt/boot
# sudo sha256sum --ignore-missing -c *-CHECKSUM
```
The *CHECKSUM file contains the values for all cloud images. The check should result in one _OK_.
For external connectivity of the VMs, the easiest way is to use MacVTap in the VM configuration. You dont need to set up a virtual bridge nor touch the critical configuration of the physical Ethernet interface of an off-premise server. Enable forwarding for both IPv4 and IPv6 (dual stack). _Libvirt_ takes care for IPv4. Nevertheless, it is advantageous to configure forwarding independent of _libvirt_.
Check the forwarding configuration:
```
# cat /proc/sys/net/ipv4/ip_forward
# cat /proc/sys/net/ipv6/conf/default/forwarding
```
In both cases, an output value of 1 is required. If necessary, activate forwarding temporarily until next reboot:
**[…]# echo 1 &gt; /proc/sys/net/ipv4/ip_forward
[…]# echo 1 &gt; /proc/sys/net/ipv6/conf/all/forwarding**
For a permanent setup create the following file:
```
# vim /etc/sysctl.d/50-enable-forwarding.conf
# local customizations
#
# enable forwarding for dual stack
net.ipv4.ip_forwarding=1
net.ipv6.conf.all.forwarding=1
```
With these preparations completed, the following two examples, creating the VMs _**app**_ and _**web**_, should work flawlessly.
#### Example 1: Quick &amp; (not really) dirty: Minimal cloud-init configuration
Installation for the _**app**_ VM begins by creating a copy of the download image as a (fully installed) virtual disk in the directory _/var/lib/libvirt/images_. This is, by convention, the virtual disk pool. The _virt-install_ program performs the installation. The parameters on _virt-install_ pass all the required information. There is no need for further intervention or preparation The parameters first specify the usual, general properties such as memory, CPU and the (non-graphical) console for the server. The parameter _-graphics none_, enforces a redirect to the terminal window. After booting you get a VM terminal prompt and immediate access from the host. Parameter _-import_ causes skipping the install task and booting from the first virtual disk specified by the _-disk_ parameter. The VM “app” is will connect to the internal virtual network thus only one network is specified by the _-network_ parameter.
The only new parameter is _-cloud-init_ without any further subparameters. This causes the generation and display of a root password, enabling a one-time login. cloud-init is executes with sensible default settings. Finally, it is deactivated and not executed during subsequent boot processes.
The VM terminal appears when installation is complete. Note that the first root login password is displayed early in the process and is used for the initial login. This password is single use and must be replace during the first login.
```
# sudo cp /var/lib/libvirt/boot/Fedora-Cloud-Base-33-1.2.x86_64.qcow2 \
/var/lib/libvirt/images/app.qcow2
# sudo virt-install --name app
--memory 3074 --cpu host --vcpus 3 --graphics none\
--os-type linux --os-variant fedora33 --import \
--disk /var/lib/libvirt/images/app.qcow2,format=qcow2,bus=virtio \
--network bridge=virbr0,model=virtio \
--cloud-init
WARNING Defaulting to --cloud-init root-password-generate=yes,disable=yes
Installation startet …
Password for first root login is: OtMQshytI0E8xZGD
Installation will continue in 10 seconds (press Enter to skip)…Running text console command: …
Connected to Domain: app
Escape character is ^] (Ctrl + ])
[ 0.000000] Linux version 5.8.15-301.fc33.x86_64 (mockbuild@bkernel01.iad2.fedoraproject …
[ 29.271451] cloud-init[721]: Cloud-init v. 19.4 finished … Datasource DataSourceNoCloud …
[FAILED] Failed to start Execute cloud user/final scripts.
See 'systemctl status cloud-final.service' for details.
[ OK ] Reached target Cloud-init target.
Fedora 33 (Cloud Edition)
Kernel 5.8.15-301.fc33.x86_64 on an x86_64 (ttyS0)
localhost login:
```
The error message is unsightly, but does not affect operation. (This might be the reason for cloud-init service remaining enabled.) You may disable it manually or remove it at all.
On the host you may check the network status:
```
# less /var/lib/libvirt/dnsmasq/virbr0.status
[
{
"ip-address": "192.168.122.109",
"mac-address": "52:54:00:57:35:3d",
"client-id": "01:52:54:00:57:35:3d",
"expiry-time": 1615665342
}
]
```
The output shows the VM got an internal IP, but no hostname because one has not yet been set. That is the first post-installation tasks to perform.
##### Post-Installation Tasks
The initially displayed password enables _root_ login and forces the setting of a new one.
Of particular interest is the network connection. Verify using these commands:
```
# ping host
# ping host.example.lan
# ping host.example.com
# ping guardian.co.ik
```
Everything is working fine out of the box. Internal and external network access is working.
The only remaining task is to set hostname
```
# hostnamectl set-hostname app.example.lan
```
After rebooting, using this command on the host again, _**less**_ _**/var/lib/libvirt/dnsmasq/virbr0.status**_ will now list a hostname. This verifies that name resolution is working.
To complete the final application software installations, perform a system update and install a Tomcat application server for the functional demo.
```
# dnf -y update && dnf -y install tomcat && systemctl enable tomcat --now && reboot
```
When installation and reboot complete, exit and close the console using _**&lt;ctrl&gt;+]**_.
The VM is automatically deactivated and not executed during subsequent boot processes. To override this, on the host, enable autostart of the **app** VM
```
# sudo virsh autostart app
```
#### Example 2: An easy way to an elaborate configuration
The **web** front end VM is more complex and there are several issues to deal with. There is a public facing interface that requires the installation of a firewall. It is unique to the cloud-init process that the internal interface is not configured persistently. Instead, it is set up anew each time the system is booted. This makes it impossible to assign a firewall zone to this interface. The public interface also provides ssh access. So for root a key file is needed to secure the login.
The virt-install cloud-init process is provisioned by two subparameters, meta-data and user-data. Each references a configuration file. These files were previously buried in a special iso image, now simulated by _virt-install_. You are free to chose where to store these files. It is best, however, to be systematic and choosing a subdirectory in the boot directory is a good choice. This example will use _/var/lib/libvirt/boot/cloud-init_.
The file referenced by the meta-data parameter contains information about the runtime environment. The name is _web-meta-data_ in this example. Here it contains just the mandatory parameter _instance-id_. The must be unique in a cloud environment, but can be chosen arbitrarily here just as in a nocloud environment.
```
# sudo mkdir /var/lib/libvirt/boot/cloud-init
# sudo vim /var/lib/libvirt/boot/cloud-init/web-meta-data
instance-id: web-app
```
The file referenced by the user-data parameter holds the main configuration work. This example uses the name _web-user-data_ . The first line must contain some kind of shebang, which cloud-init uses to determine the format of the following data. The formatting itself is _yaml_. The _web-user-data_ file defines several steps:
1. setting the hostname
2. set up the user root with the public RSA key copied into the file as well as the fallback account “hostmin” (or alike). The latter is enabled to log in by password and assigned to the group wheel
3. set up a first-time password for both users for initial login which must be changed on first login
4. install required additional packages , e.g. the firewall, fail2ban, postfix (needed by fail2ban) and the webserver
5. some packages need additional configuration files
6. the VM needs an update of all packages
7. several configuration commands are required
1. assign zone trusted to the interface eth1 (2nd position in the dbus path, so the order of the network parameters when calling _libvirt_ is crucial!) and rename it according to naming convention. The modification also persists to a configuration file (still in /etc/sysconfig/network-scripts/ )
2. start the firewall and add the web services
3. finally disable cloud-init
Once the configuration files are completed it eliminates what would be a time consuming process if done manually. This efficiency makes the use of cloud images attractive. The definition of _web-user-data_ follows:
```
# vim /var/lib/libvirt/boot/cloud-init/web-user-data
# cloud-config
# (1) setting hostname
preserve_hostname: False
hostname: web
fqdn: web.example.com
# (2) set up root and fallback account including rsa key copied into this file
users:
- name: root
ssh-authorized-keys:
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQA…jSMt9rC4uKDPR8whgw==
- name: hostmin
groups: users,wheel
ssh_pwauth: True
ssh-authorized-keys:
- ssh-rsa AAAAB3NzaC1yc2EAAAIAQDix...Mt9rC4uKDPR8whgw==
# (3) set up a first-time password for both accounts
chpasswd:
list: |
root:myPassword
hostmin:topSecret
expire: True
# (4) install additional required packages
packages:
- firewalld
- postfix
- fail2ban
- vim
- httpd
- mod_ssl
- letsencrypt
# (5) some packages need additional configuration files
write_files:
- path: /etc/fail2ban/jail.local
content: |
# /etc/fail2ban/jail.local
# Jail configuration local customization
# Adjust the default configuration's default values
[DEFAULT]
##ignoreip = /24 /32
bantime = 6600
backend = auto
# The main configuration file defines all services but
# deactivates them by default. Activate those needed
[sshd]
enabled = true
# detect password authentication failures
[apache-auth]
enabled = true
# detect spammer robots crawling email addresses
[apache-badbots]
enabled = true
# detect Apache overflow attempts
[apache-overflows]
enabled = true
- path: /etc/httpd/conf.d/vhost_default.conf
content: |
<VirtualHost *:80>
ServerAdmin root@localhost
DirectoryIndex index.jsp
DocumentRoot /var/www/html
<Directory "/var/www.html">
Options Indexes FollowSymLinks
AllowOverride none
# Allow open access:
Require all granted
</Directory>
ProxyPass / http://app:8080/
</VirtualHost>
# (6) perform a package upgrade
package_upgrade: true
# (7) several configuration commands are executed on first boot
runcmd:
# (a.) assign a zone to internal interface as well as some other adaptations.
# results in the writing of a configuration file
# IMPORTANT: internal interface have to be specified SECOND after external
- nmcli con mod path 2 con-name eth1 connection.zone trusted
- nmcli con mod path 2 con-name 'System eth1' ipv6.method disabled
- nmcli con up path 2
# (b.) activate and configure firewall and additional services
- systemctl enable firewalld --now
- firewall-cmd --permanent add-service=http
- firewall-cmd --permanent add-service=https
- firewall-cmd --reload
- systemctl enable fail2ban --now
# compensate for a SELinux port handling issue
- setsebool httpd_can_network_connect 1 -P
- systemctl enable httpd -now
# (c.) finally disable cloud-init
- systemctl disable cloud-init
- reboot
# done
```
A detailed overview of the user-data configuration options is provided in the examples section of the [cloud-init project documentation][8].
After completing the configuration files, initiate the virt-install process. Adjust the values of CPU, memory, external network interface etc. as required.
```
# sudo virt-install --name web \
--memory 3072 --cpu host --vcpus 3 --graphics none \
--os-type linux --os-variant fedora33 --import \
--disk /var/lib/libvirt/images/web.qcow2,format=qcow2,bus=virtio, size=20 \
--network type=direct,source=enp1s0,source_mode=bridge,model=virtio \
--network bridge=virbr0,model=virtio \
--cloud-init meta-data=/var/lib/libvirt/boot/cloud-init/web-meta-data,user-data=/var/lib/libvirt/boot/cloud-init/web-user-data
```
If the network environment issues IP addresses based on MAC addresses via DHCP, add the MAC address to the the first network configuration:
```
--network type=direct,source=enp1s0,source_mode=bridge,mac=52:54:00:93:97:46,model=virtio
```
Remember, that the first 3 pairs in the MAC address must be the sequence 52:54:00 for KVM virtual machines.
Back on the host enable autostart of the VM:
```
# virsh autostart web
```
Everything is complet. Direct your desktop browser to your <http://example.com> domain and enjoy a look at the tomcat webapps screen (after ignoring the warning about an insecure connection).
##### Configuring a static address
According to the specifications a static network connection is configured in meta-data. A configuration would look like this:
```
# vim /var/lib/libdir/boot/cloud-init/web-meta-data
instance-id: web-app
network-interfaces: |
iface eth0 inet static
address 192.168.1.10
netmask 255.255.255.0
gateway 192.168.1.254
```
_Cloud-init_ will create a configuration file accordingly. But there are 2 issues
* The configuration file is created after a default initialization of the interface via dhcp and the interface is not reinitialized.
* The generated configuration file includes the setting _onboot=no_ so after a reboot there is no connection either.
There are several hints that this is a bug that has existed for a long time so manual intervention is required.
It is probably easier and more efficient to do without the networks specification in meta-data and make an adjustment manually on the basis of the default initialization in user-data. Perform the following before the configuration of the internal network:
```
# nmcli con mod path 1 ipv4.method static ipv4.addresses '192.168.158.240/24' ipv4.gateway '192.168.158.1' ipv4.dns '192.168.158.1'
# nmcli con mod path 1 ipv6.method static ipv6.addresses '2003:ca:7f06:2c00:5054:ff:fed6:5b27/64' ipv6.gateway 'fe80::1' ipv6.dns '003:ca:7f06:2c00::add:9999'
# nmcli con up path 1
```
Doing this, the connection is immediately reset to the new specification and the configuration file is adjusted immediately. Remember to adjust the configuration values as needed.
Alternatively, the 3 statements can be made part of the user-data file and adapted or commented in or out as required. The corresponding part of the file would look like
```
...
# (7.) several configuration commands are executed on first boot
runcmd:
# If needed, convert interface eth0 as static
# comment in and modify as required
#- nmcli con mod path 1 ipv4.method static ipv4.addresses '<IPv4>/24' ipv4.gateway '<IPv4>' ipv4.dns 'IPv4
#- nmcli con mod path 1 ipv6.method static ipv6.addresses '<IPv6>/64' ipv6.gateway '<IPv6>' ipv6.dns '<IPv6>'
#- nmcli con up path 1
# (a) assign a zone to internal interface as well as some other adaptations.
# results in the writing of a configuration file
# IMPORTANT: internal interface have to be specified SECOND after external
- nmcli con mod path 2 con-name eth1 connection.zone trusted
- ...
```
Again, adjust the &lt;IPv4&gt;, &lt;IPv6&gt;, etc. configuration values as needed!
Configuring the cloud-init process by virt-install version 3 is highly efficient and flexible. You may create a dedicated set of files for each VM or you may keep one set of generic files and adjust them by commenting in and out as required. A combination of both can be use. You can quickly and easily change settings to test suitability for your purposes.
In summary, while the use of Fedora Cloud Base Images comes with some inconveniences and suffers from shortcomings in documentation, Fedora Cloud Base images and virt-install version 3 is a great combination for quickly and efficiently creating virtual machines for Fedora Server.
--------------------------------------------------------------------------------
via: https://fedoramagazine.org/setting-up-a-vm-on-fedora-server-using-cloud-images-and-virt-install-version-3/
作者:[pboy][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://fedoramagazine.org/author/pboy/
[b]: https://github.com/lujun9972
[1]: https://fedoramagazine.org/wp-content/uploads/2021/03/cloud_base_via_virt-install-816x345.jpg
[2]: https://unsplash.com/@maxkuk?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText
[3]: https://unsplash.com/s/photos/cloud-computing?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText
[4]: https://alt.fedoraproject.org/cloud/
[5]: https://fedoramagazine.org/create-virtual-machines-with-cockpit-in-fedora/
[6]: https://fedoramagazine.org/vagrant-qemukvm-fedora-devops-sysadmin/
[7]: https://blog.christophersmart.com/2016/06/17/booting-fedora-24-cloud-image-with-kvm/
[8]: https://cloudinit.readthedocs.io/en/latest/topics/examples.html

View File

@@ -1,288 +0,0 @@
[#]: subject: (Playing with modular synthesizers and VCV Rack)
[#]: via: (https://fedoramagazine.org/vcv-rack-modular-synthesizers/)
[#]: author: (Yann Collette https://fedoramagazine.org/author/ycollet/)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
Playing with modular synthesizers and VCV Rack
======
![][1]
You know about using Fedora Linux to write code, books, play games, and listen to music. You can also do system simulation, work on electronic circuits, work with embedded systems too via [Fedora Labs][2]. But you can also make music with the VCV Rack software. For that, you can use to [Fedora Jam][3] or work from a standard Fedora Workstation installation with the [LinuxMAO Copr][4] repository enabled. This article describes how to use modular synthesizers controlled by Fedora Linux.
### Some history
The origin of the modular synthesizer dates back to the 1950s and was soon followed in the 60s by the Moog modular synthesizer. [Wikipedia has a lot more on the history][5].
![Moog synthesizer circa 1975][6]
But, by the way, what is a modular synthesizer ?
These synthesizers are made of hardware “blocks” or modules with specific functions like oscillators, amplifier, sequencer, and other various functions. The blocks are connected together by wires. You make music with these connected blocks by manipulating knobs. Most of these modular synthesizers came without keyboard.
![][7]
Modular synthesizers were very common in the early days of progressive rock (with Emerson Lake and Palmer) and electronic music (Klaus Schulze, for example). 
After a while people forgot about modular synthesizers because they were cumbersome, hard to tune, hard to fix, and setting a patch (all the wires connecting the modules) was a time consuming task not very easy to perform live. Price was also a problem because systems were mostly sold as a small series of modules, and you needed at least 10 of them to have a decent set-up.
In the last few years, there has been a rebirth of these synthesizers. Doepfer produces some affordable models and a lot of modules are also available and have open sources schematics and codes (check [Mutable instruments][8] for example).
But, a few years ago came … [VCV Rack.][9] VCV Rack stands for **V**oltage **C**ontrolled **V**irtual Rack: software-based modular synthesizer lead by Andrew Belt. His first commit on [GitHub][10] was Monday Nov 14 18:34:40 2016. 
### Getting started with VCV Rack
#### Installation
To be able to use VCV Rack, you can either go to the [VCV Rack web site][9] and install a binary for Linux or, you can activate a Copr repository dedicated to music: the [LinuxMAO Copr][4] repository (disclaimer: I am the man behind this Copr repository). As a reminder, Copr is not officially supported by Fedora infrastructure. Use packages at your own risk.
Enable the repository with:
```
sudo dnf copr enable ycollet/linuxmao
```
Then install VCV Rack:
```
sudo dnf install Rack-v1
```
You can now start VCV Rack from the console of via the Multimedia entry in the start menu:
```
$ Rack &
```
![][11]
#### Add some modules
The first step is now to clean up everything and leave just the **AUDIO-8** module. You can remove modules in various ways:
* Click on a module and hit the backspace key
* Right click on a module and click “delete”
The **AUDIO-8** module allows you to connect from and to audio devices. Here are the features for this module.
![][12]
Now its time to produce some noise (for the music, well see that later).
Right click inside VCV Rack (but outside of a module) and a module search window will appear. 
![][13]
Enter “VCO-2” in the search bar and click on the image of the module. This module is now on VCV Rack.
To move a module: click and drag the module.
To move a group of modules, hit shit + click + drag a module and all the modules on the right of the dragged modules will move with the selected module.
![][14]
Now you need to connect the modules by drawing a wire between the “OUT” connector of **VCO-2** module and the “1” “TO DEVICE” of **AUDIO-8** module.
Left-click on the “OUT” connector of the **VCO-2** module and while keeping the left-click, drag your mouse to the “1” “TO DEVICE” of the **AUDIO-8** module. Once on this connector, release your left-click. 
![][15]
To remove a wire, do a right-click on the connector where the wire is connected.
To draw a wire from an already connected connector, hold “ctrl+left+click” and draw the wire. For example, you can draw a wire from “OUT” connector of module **VCO-2** to the “2” “TO DEVICE” connector of **AUDIO-8** module.
#### What are these wires ?
Wires allow you to control various part of the module. The information handled by these wires are Control Voltages, Gate signals, and Trigger signals.
**CV** ([Control Voltages][16]): These typically control pitch and range between a minimum value around -1 to -5 volt and a maximum value between 1 and 5 volt.
What is the **GATE** signal you find on some modules? Imagine a keyboard sending out on/off data to an amplifier module: its voltage is at zero when no key is  pressed and jumps up to max level (5v for example) when a key is pressed; release the key, and the voltage goes back to zero again. A **GATE** signal can be emitted by things other than a keyboard. A clock module, for example, can emit gate signals.
Finally, what is a **TRIGGER** signal you find on some modules? Its a square pulse which starts when you press a key and stops after a while.
In the modular world, **gate** and **trigger** signals are used to trigger drum machines, restart clocks, reset sequencers and so on. 
#### Connecting everybody
Lets control an oscillator with a CV signal. But before that, remove your **VCO-2** module (click on the module and hit backspace).
Do a right-click on VCV Rack a search for these modules:
* **VCO-1** (a controllable oscillator)
* **LFO-1** (a low frequency oscillator which will control the frequency of the **VCO-1**)
Now draw wires:
* between the “SAW” connector of the **LFO-1** module and the “V/OCT” (Voltage per Octave) connector of the **VCO-1** module
* between the “SIN” connector of the **VCO-1** module and the “1” “TO DEVICE” of the **AUDIO-8** module
![][17]
You can adjust the range of the frequency by turning the FREQ knob of the **LFO-1** module.
You can also adjust the low frequency of the sequence by turning the FREQ knob of the **VCO-1** module.
### The Fundamental modules for VCV Rack
When you install the **Rack-v1**, the **Rack-v1-Fundamental** package is automatically installed. **Rack-v1** only installs the rack system, with input / output modules, but without other basic modules.
In the Fundamental VCV Rack packages, there are various modules available.
![][18]
Some important modules to have in mind:
* **VCO**: Voltage Controlled Oscillator
* **LFO**: Low Frequency Oscillator
* **VCA**: Voltage Controlled Amplifier
* **SEQ**: Sequencers (to define a sequence of voltage / notes)
* **SCOPE**: an oscilloscope, very useful to debug your connexions
* **ADSR**: a module to generate an envelope for a note. ADSR stands for **A**ttack / **D**ecay / **S**ustain / **R**elease
And there are a lot more functions available. I recommend you watch tutorials related to VCV Rack on YouTube to discover all these functionalities, in particular the Video Channel of [Omri Cohen][19].
### What to do next
Are you limited to the Fundamental modules? No, certainly not! VCV Rack provides some closed sources modules (for which youll need to pay) and a lot of other modules which are open source. All the open source modules are packages for Fedora 32 and 33. How many VCV Rack packages are available ?
```
sudo dnf search rack-v1 | grep src | wc -l
150
```
And counting.  Each month new packages appear. If you want to install everything at once, run:
```
sudo dnf install `dnf search rack-v1 | grep src | sed -e "s/\(^.*\)\.src.*/\1/"`
```
Here are some recommended modules to start with.
* BogAudio (dnf install rack-v1-BogAudio)
* AudibleInstruments (dnf install rack-v1-AudibleInstruments)
* Valley (dnf install rack-v1-Valley)
* Befaco (dnf install rack-v1-Befaco)
* Bidoo (dnf install rack-v1-Bidoo)
* VCV-Recorder (dnf install rack-v1-VCV-Recorder)
### A more complex case
![][20]
From Fundamental, use **MIXER**, **AUDIO-8**, **MUTERS**, **SEQ-3**, **VCO-1**, **ADSR**, **VCA**.
Use:
* **Plateau** module from Valley package (its an enhanced reverb).
* **BassDrum9** from DrumKit package.
* **HolonicSystems-Gaps** from HolonicSystems-Free package.
How it sounds: checkout [this video][21] on my YouTube channel.
### Managing MIDI
VCV Rack as a bunch of modules dedicated to MIDI management.
![][22]
With these modules and with a tool like the Akai LPD-8:
![][23]
You can easily control knob in VCV Rack modules from a real life device.
Before buying some devices, check its Linux compatibility. Normally every “USB Class Compliant” device works out of the box in every Linux distribution.
The MIDI → Knob mapping is done via the “MIDI-MAP” module. Once you have selected the MIDI driver (first line) and MIDI device (second line), click on “unmapped”. Then, touch a knob you want to control on a module (for example the “FREQ” knob of the VCO-1 Fundamental module). Now, turn the knob of the MIDI device and there you are; the mapping is done.
### Artistic scopes
Last topic of this introduction paper: the scopes.
VCV Rack has several standard (and useful) scopes. The **SCOPE** module from Fundamental for example.
But it also has some interesting scopes.
![][24]
This used 3 **VCO-1** modules from Fundamental and a **fullscope** from wiqid-anomalies.
The first connector at the top of the scope corresponds to the X input. The one below is the Y input and the other one below controls the color of the graph.
For the complete documentation of this module, check:
* the documentation of [wigid-anomalies][25]
* the documentation of the [fullscope][26] module
* the github repository of the [wigid-anomalies][27] module
### For more information
If youre looking for help or want to talk to the VCV Rack Community, visit their [Discourse forum][28]. You can get _patches_ (a patch is the file saved by VCV Rack) for VCV Rack on [Patch Storage][29].
Check out how vintage synthesizers looks like on [Vintage Synthesizer Museum][30] or [Googles online exhibition][31]. The documentary “[I Dream of Wires][32]” provides a look at the history of modular synthesizers. Finally, the book _[Developing Virtual Syntehsizers with VCV Rack][33]_ provides more depth.
--------------------------------------------------------------------------------
via: https://fedoramagazine.org/vcv-rack-modular-synthesizers/
作者:[Yann Collette][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://fedoramagazine.org/author/ycollet/
[b]: https://github.com/lujun9972
[1]: https://fedoramagazine.org/wp-content/uploads/2021/03/music_synthesizers-816x345.jpg
[2]: https://labs.fedoraproject.org/
[3]: https://fedoraproject.org/wiki/Fedora_Jam_Audio_Spin
[4]: https://copr.fedorainfracloud.org/coprs/ycollet/linuxmao/
[5]: https://en.wikipedia.org/wiki/Modular_synthesizer
[6]: https://fedoramagazine.org/wp-content/uploads/2021/03/Moog_Modular_55_img1-1024x561.png
[7]: https://fedoramagazine.org/wp-content/uploads/2021/03/modular_synthesizer_-_jam_syntotek_stockholm_2014-09-09_photo_by_henning_klokkerasen_edit-1.jpg
[8]: https://mutable-instruments.net/
[9]: https://vcvrack.com/
[10]: https://github.com/VCVRack/Rack
[11]: https://fedoramagazine.org/wp-content/uploads/2021/03/Screenshot_20210309_215239-1024x498.png
[12]: https://fedoramagazine.org/wp-content/uploads/2021/03/Screenshot_20210309_232052.png
[13]: https://fedoramagazine.org/wp-content/uploads/2021/03/Screenshot_20210310_191531-1024x479.png
[14]: https://fedoramagazine.org/wp-content/uploads/2021/03/Screenshot_20210309_221358.png
[15]: https://fedoramagazine.org/wp-content/uploads/2021/03/Screenshot_20210309_222055.png
[16]: https://en.wikipedia.org/wiki/CV/gate
[17]: https://fedoramagazine.org/wp-content/uploads/2021/03/Screenshot_20210309_223840.png
[18]: https://fedoramagazine.org/wp-content/uploads/2021/03/Fundamental-showcase-1024x540.png
[19]: https://www.youtube.com/channel/UCuWKHSHTHMV_nVSeNH4gYAg
[20]: https://fedoramagazine.org/wp-content/uploads/2021/03/Screenshot_20210309_233506.png
[21]: https://www.youtube.com/watch?v=HhJ_HY2rN5k
[22]: https://fedoramagazine.org/wp-content/uploads/2021/03/Screenshot_20210310_193452-1024x362.png
[23]: https://fedoramagazine.org/wp-content/uploads/2021/03/235492.jpg
[24]: https://fedoramagazine.org/wp-content/uploads/2021/03/Screenshot_20210310_195044.png
[25]: https://library.vcvrack.com/wiqid-anomalies
[26]: https://library.vcvrack.com/wiqid-anomalies/fullscope
[27]: https://github.com/wiqid/anomalies
[28]: https://community.vcvrack.com/
[29]: https://patchstorage.com/platform/vcv-rack/
[30]: https://vintagesynthesizermuseum.com/
[31]: https://artsandculture.google.com/story/7AUBadCIL5Tnow
[32]: http://www.idreamofwires.org/
[33]: https://www.leonardo-gabrielli.info/vcv-book

View File

@@ -1,181 +0,0 @@
[#]: subject: (Read and write files with Groovy)
[#]: via: (https://opensource.com/article/21/4/groovy-io)
[#]: author: (Chris Hermansen https://opensource.com/users/clhermansen)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
Read and write files with Groovy
======
Learn how the Groovy programming language handles reading from and
writing to files.
![Woman programming][1]
Two common tasks that new programmers need to learn are how to read from and write to files stored on a computer. Some examples are when data and configuration files created in one application need to be read by another application, or when a third application needs to write info, warnings, and errors to a log file or to save its results for someone else to use.
Every language has a few different ways to read from and write to files. This article covers some of these details in the [Groovy programming language][2], which is based on Java but with a different set of priorities that make Groovy feel more like Python. The first thing a new-to-Groovy programmer sees is that it is much less verbose than Java. The next observation is that it is (by default) dynamically typed. The third is that Groovy has closures, which are somewhat like lambdas in Java but provide access to the entire enclosing context (Java lambdas restrict what can be accessed).
My fellow correspondent Seth Kenlon has written about [Java input and output (I/O)][3]. I'll jump off from his Java code to show you how it's done in Groovy.
### Install Groovy
Since Groovy is based on Java, it requires a Java installation. You may be able to find a recent and decent version of Java and Groovy in your Linux distribution's repositories. Or you can install Groovy by following the instructions on [Groovy's download page][4]. A nice alternative for Linux users is [SDKMan][5], which you can use to get multiple versions of Java, Groovy, and many other related tools. For this article, I'm using my distro's OpenJDK11 release and SDKMan's Groovy 3.0.7 release.
### Read a file with Groovy
Start by reviewing Seth's Java program for reading files:
```
import java.io.File;
import java.util.Scanner;
import java.io.FileNotFoundException;
public class Ingest {
  public static void main([String][6][] args) {
      try {
          [File][7] myFile = new [File][7]("example.txt");
          Scanner myScanner = new Scanner(myFile);
          while (myScanner.hasNextLine()) {
              [String][6] line = myScanner.nextLine();
              [System][8].out.println(line);
          }
          myScanner.close();
      } catch ([FileNotFoundException][9] ex) {
          ex.printStackTrace();
      } //try
    } //main
} //class
```
Now I'll do the same thing in Groovy:
```
def myFile = new [File][7]('example.txt')
def myScanner = new Scanner(myFile)
while (myScanner.hasNextLine()) {
        def line = myScanner.nextLine()
        println(line)
}
myScanner.close()
```
Groovy looks like Java but less verbose. The first thing to notice is that all those `import` statements are already done in the background. And since Groovy is partly intended to be a scripting language, by omitting the definition of the surrounding `class` and `public static void main`, Groovy will construct those things in the background.
The semicolons are also gone. Groovy supports their use but doesn't require them except in cases like when you want to put multiple statements on the same line. Aaaaaaaaand the single quotes—Groovy supports either single or double quotes for delineating strings, which is handy when you need to put double quotes inside a string, like this:
```
`'"I like this Groovy stuff", he muttered to himself.'`
```
Note also that `try...catch` is gone. Groovy supports `try...catch` but doesn't require it, and it will give a perfectly good error message and stack trace just like the `ex.printStackTrace()` call does in the Java example.
Groovy adopted the `def` keyword and inference of type from the right-hand side of a statement long before Java came up with the `var` keyword, and Groovy allows it everywhere. Aside from using `def`, though, the code that does the main work looks quite similar to the Java version. Oh yeah, except that Groovy also has this nice metaprogramming ability built in, which among other things, lets you write `println()` instead of `System.out.println()`. This similarity is way more than skin deep and allows Java programmers to get traction with Groovy very quickly.
And just like Python programmers are always looking for the pythonic way to do stuff, there is Groovy that looks like Java, and then there is… groovier Groovy. This solves the same problem but uses Groovy's `with` method to make the code more DRY ("don't repeat yourself") and to automate closing the input file:
```
new Scanner(new [File][7]('example.txt')).with {
    while (hasNextLine()) {
      def line = nextLine()
      println(line)
    }
}
```
What's between `.with {` and `}` is a closure body. Notice that you don't need to write `myScanner.hasNextLine()` nor `myScanner.nextLine()` as `with` exposes those methods directly to the closure body.  Also the with gets rid of the need to code myScanner.close() and so we don't actually need to declare myScanner at all.
Run it:
```
$ groovy ingest1.groovy
Caught: java.io.[FileNotFoundException][9]: example.txt (No such file or directory)
java.io.[FileNotFoundException][9]: example.txt (No such file or directory)
        at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native [Method][10])
        at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at ingest1.run(ingest1.groovy:1)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native [Method][10])
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
$
```
Note the "file not found" exception; this is because there isn't a file called `example.txt` yet. Note also that the files are from things like `java.io`.
So I'll write something into that file…
### Write data to a file with Groovy
Combining what I shared previously about, well, being "groovy":
```
new [FileWriter][11]("example.txt", true).with {
        write("Hello world\n")
        flush()
}
```
Remember that `true` after the file name means "append to the file," so you can run this a few times:
```
$ groovy exgest.groovy
$ groovy exgest.groovy
$ groovy exgest.groovy
$ groovy exgest.groovy
```
Then you can read the results with `ingest1.groovy`:
```
$ groovy ingest1.groovy
Hello world
Hello world
Hello world
Hello world
$
```
The call to `flush()` is used because the `with` / `write` combo didn't do a flush before close. Groovy isn't always shorter!
### Groovy resources
The Apache Groovy site has a lot of great [documentation][12]. Another great Groovy resource is [Mr. Haki][13]. And a really great reason to learn Groovy is to learn [Grails][14], which is a wonderfully productive full-stack web framework built on top of excellent components like Hibernate, Spring Boot, and Micronaut.
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/4/groovy-io
作者:[Chris Hermansen][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/clhermansen
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/programming-code-keyboard-laptop-music-headphones.png?itok=EQZ2WKzy (Woman programming)
[2]: https://groovy-lang.org/
[3]: https://opensource.com/article/21/3/io-java
[4]: https://groovy.apache.org/download.html
[5]: https://sdkman.io/
[6]: http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+string
[7]: http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+file
[8]: http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+system
[9]: http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+filenotfoundexception
[10]: http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+method
[11]: http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+filewriter
[12]: https://groovy-lang.org/documentation.html
[13]: https://blog.mrhaki.com/
[14]: https://grails.org/

View File

@@ -1,179 +0,0 @@
[#]: subject: (Scaling Microservices on Kubernetes)
[#]: via: (https://www.linux.com/news/scaling-microservices-on-kubernetes/)
[#]: author: (Dan Brown https://training.linuxfoundation.org/announcements/scaling-microservices-on-kubernetes/)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
Scaling Microservices on Kubernetes
======
_By Ashley Davis_
_*This article was originally published at [TheNewStack][1]_
Applications built on microservices can be scaled in multiple ways. We can scale them to support development by larger development teams and we can also scale them up for better performance. Our application can then have a higher capacity and can handle a larger workload.
Using microservices gives us granular control over the performance of our application. We can easily measure the performance of our microservices to find the ones that are performing poorly, are overworked, or are overloaded at times of peak demand. Figure 1 shows how we might use the [Kubernetes dashboard][2] to understand CPU and memory usage for our microservices.
<https://cdn.thenewstack.io/media/2021/03/748d12fb-image9.png>
_Figure 1: Viewing CPU and memory usage for microservices in the Kubernetes dashboard_
If we were using a monolith, however, we would have limited control over performance. We could vertically scale the monolith, but thats basically it.
Horizontally scaling a monolith is much more difficult; and we simply cant independently scale any of the “parts” of a monolith. This isnt ideal, because it might only be a small part of the monolith that causes the performance problem. Yet, we would have to vertically scale the entire monolith to fix it. Vertically scaling a large monolith can be an expensive proposition.
Instead, with microservices, we have numerous options for scaling. For instance, we can independently fine-tune the performance of small parts of our system to eliminate bottlenecks and achieve the right mix of performance outcomes.
There are also many advanced ways we could tackle performance issues, but in this post, well overview a handful of relatively simple techniques for scaling our microservices using [Kubernetes][3]:
1. Vertically scaling the entire cluster
2. Horizontally scaling the entire cluster
3. Horizontally scaling individual microservices
4. Elastically scaling the entire cluster
5. Elastically scaling individual microservices
Scaling often requires risky configuration changes to our cluster. For this reason, you shouldnt try to make any of these changes directly to a production cluster that your customers or staff are depending on.
Instead, I would suggest that you create a new cluster and use **blue-green deployment**, or a similar deployment strategy, to buffer your users from risky changes to your infrastructure.
### **Vertically Scaling the Cluster**
As we grow our application, we might come to a point where our cluster generally doesnt have enough compute, memory or storage to run our application. As we add new microservices (or replicate existing microservices for redundancy), we will eventually max out the nodes in our cluster. (We can monitor this through our cloud vendor or the Kubernetes dashboard.)
At this point, we must increase the total amount of resources available to our cluster. When scaling microservices on a [Kubernetes cluster][4], we can just as easily make use of either vertical or horizontal scaling. Figure 2 shows what vertical scaling looks like for Kubernetes.
<https://cdn.thenewstack.io/media/2021/03/00c4f89c-image8.png>
_Figure 2: Vertically scaling your cluster by increasing the size of the virtual machines (VMs)_
We scale up our cluster by increasing the size of the virtual machines (VMs) in the node pool. In this example, we increased the size of three small-sized VMs so that we now have three large-sized VMs. We havent changed the number of VMs; weve just increased their size — scaling our VMs vertically.
Listing 1 is an extract from Terraform code that provisions a cluster on Azure; we change the vm_size field from Standard_B2ms to Standard_B4ms. This upgrades the size of each VM in our Kubernetes node pool. Instead of two CPUs, we now have four (one for each VM). As part of this change, memory and hard-drive for the VM also increase. If you are deploying to AWS or GCP, you can use this technique to vertically scale, but those cloud platforms offer different options for varying VM sizes.
We still only have a single VM in our cluster, but we have increased our VMs size. In this example, scaling our cluster is as simple as a code change. This is the power of infrastructure-as-code, the technique where we store our infrastructure configuration as code and make changes to our infrastructure by committing code changes that trigger our continuous delivery (CD) pipeline
<https://cdn.thenewstack.io/media/2021/03/32f268d3-image2.png>
_Listing 1: Vertically scaling the cluster with Terraform (an extract)_
### Horizontally Scaling the Cluster
In addition to vertically scaling our cluster, we can also scale it horizontally. Our VMs can remain the same size, but we simply add more VMs.
By adding more VMs to our cluster, we spread the load of our application across more computers. Figure 3 illustrates how we can take our cluster from three VMs up to six. The size of each VM remains the same, but we gain more computing power by having more VMs.
<https://cdn.thenewstack.io/media/2021/03/81dea0ef-image1.png>
_Figure 3: Horizontally scaling your cluster by increasing the number of VMs_
Listing 2 shows an extract of Terraform code to add more VMs to our node pool. Back in listing 1, we had node_count set to 1, but here we have changed it to 6. Note that we reverted the vm_size field to the smaller size of Standard_B2ms. In this example, we increase the number of VMs, but not their size; although there is nothing stopping us from increasing both the number and the size of our VMs.
Generally, though, we might prefer horizontal scaling because it is less expensive than vertical scaling. Thats because using many smaller VMs is cheaper than using fewer but bigger and higher-priced VMs.
<https://cdn.thenewstack.io/media/2021/03/31716e5c-image6.png>
_Listing 2: Horizontal scaling the cluster with Terraform (an extract)_
### Horizontally Scaling an Individual Microservice
Assuming our cluster is scaled to an adequate size to host all the microservices with good performance, what do we do when individual microservices become overloaded? (This can be monitored in the Kubernetes dashboard.)
Whenever a microservice becomes a performance bottleneck, we can horizontally scale it to distribute its load over multiple instances. This is shown in figure 4.
<https://cdn.thenewstack.io/media/2021/03/39ee5bd0-image4.png>
_Figure 4: Horizontally scaling a microservice by replicating it_
We are effectively giving more compute, memory and storage to this particular microservice so that it can handle a bigger workload.
Again, we can use code to make this change. We can do this by setting the replicas field in the specification for our Kubernetes deployment or pod as shown in listing 3.
<https://cdn.thenewstack.io/media/2021/03/5acaf6b1-image5.png>
_Listing 3: Horizontally scaling a microservice with Terraform (an extract)_
Not only can we scale individual microservices for performance, we can also horizontally scale our microservices for redundancy, creating a more fault-tolerant application. By having multiple instances, there are others available to pick up the load whenever any single instance fails. This allows the failed instance of a microservice to restart and begin working again.
### Elastic Scaling for the Cluster
Moving into more advanced territory, we can now think about elastic scaling. This is a technique where we automatically and dynamically scale our cluster to meet varying levels of demand.
Whenever a demand is low, [Kubernetes][5] can automatically deallocate resources that arent needed. During high-demand periods, new resources are allocated to meet the increased workload. This generates substantial cost savings because, at any given moment, we only pay for the resources necessary to handle our applications workload at that time.
We can use elastic scaling at the cluster level to automatically grow our clusters that are nearing their resource limits. Yet again, when using Terraform, this is just a code change. Listing 4 shows how we can enable the Kubernetes autoscaler and set the minimum and maximum size of our node pool.
Elastic scaling for the cluster works by default, but there are also many ways we can customize it. Search for “auto_scaler_profile” in [the Terraform documentation][6] to learn more.
<https://cdn.thenewstack.io/media/2021/03/feb61037-image3.png>
_Listing 4: Enabling elastic scaling for the cluster with Terraform (an extract)_
### Elastic Scaling for an Individual Microservice
We can also enable elastic scaling at the level of an individual microservice.
Listing 5 is a sample of Terraform code that gives microservices a “burstable” capability. The number of replicas for the microservice is expanded and contracted dynamically to meet the varying workload for the microservice (bursts of activity).
The scaling works by default, but can be customized to use other metrics. See the [Terraform documentation][7] to learn more. To learn more about pod auto-scaling in Kubernetes, [see the Kubernetes docs][8].
<https://cdn.thenewstack.io/media/2021/03/d4bd53af-image7.png>
_Listing 5: Enabling elastic scaling for a microservice with Terraform_
### About the Book: Bootstrapping Microservices
You can learn about building applications with microservices with [Bootstrapping Microservices][9].
Bootstrapping Microservices is a practical and project-based guide to building applications with microservices. It will take you all the way from building one single microservice all the way up to running a microservices application in production on [Kubernetes][10], ending up with an automated continuous delivery pipeline and using _infrastructure-as-code_ to push updates into production.
### Other Kubernetes Resources
This post is an extract from _Bootstrapping Microservices_ and has been a short overview of the ways we can scale microservices when running them on Kubernetes.
We specify the configuration for our infrastructure using Terraform. Creating and updating our infrastructure through code in this way is known as **intrastructure-as-code**, as a technique that turns working with infrastructure into a coding task and paved the way for the DevOps revolution.
To learn more about [Kubernetes][11], please see [the Kubernetes documentation][12] and the free [Introduction to Kubernetes][13] training course.
To learn more about working with Kubernetes using Terraform, please see [the Terraform documentation][14].
**About the Author, Ashley Davis**
Ashley is a software craftsman, entrepreneur, and author with over 20 years of experience in software development, from coding to managing teams, then to founding companies. He is the CTO of Sortal, a product that automatically sorts digital assets through the magic of machine learning.
The post [Scaling Microservices on Kubernetes][15] appeared first on [Linux Foundation Training][16].
--------------------------------------------------------------------------------
via: https://www.linux.com/news/scaling-microservices-on-kubernetes/
作者:[Dan Brown][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://training.linuxfoundation.org/announcements/scaling-microservices-on-kubernetes/
[b]: https://github.com/lujun9972
[1]: https://thenewstack.io/scaling-microservices-on-kubernetes/
[2]: https://coding-bootcamps.com/blog/kubernetes-evolution-from-virtual-servers-and-kubernetes-architecture.html
[3]: https://learn.coding-bootcamps.com/p/complete-live-training-for-mastering-devops-and-all-of-its-tools
[4]: https://blockchain.dcwebmakers.com/blog/advance-topics-for-deploying-and-managing-kubernetes-containers.html
[5]: http://myhsts.org/tutorial-review-of-17-essential-topics-for-mastering-kubernetes.php
[6]: https://www.terraform.io/docs/providers/azurerm/r/kubernetes_cluster.html
[7]: http://www.terraform.io/docs/providers/kubernetes/r/horizontal_pod_autoscaler.html
[8]: https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/
[9]: https://www.manning.com/books/bootstrapping-microservices-with-docker-kubernetes-and-terraform
[10]: https://coding-bootcamps.com/blog/build-containerized-applications-with-golang-on-kubernetes.html
[11]: https://learn.coding-bootcamps.com/p/live-training-class-for-mastering-kubernetes-containers-and-cloud-native
[12]: https://kubernetes.io/docs/home/
[13]: https://training.linuxfoundation.org/training/introduction-to-kubernetes/
[14]: https://registry.terraform.io/providers/hashicorp/kubernetes/latest
[15]: https://training.linuxfoundation.org/announcements/scaling-microservices-on-kubernetes/
[16]: https://training.linuxfoundation.org/

View File

@@ -1,145 +0,0 @@
[#]: subject: (Use Apache Superset for open source business intelligence reporting)
[#]: via: (https://opensource.com/article/21/4/business-intelligence-open-source)
[#]: author: (Maxime Beauchemin https://opensource.com/users/mistercrunch)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
Use Apache Superset for open source business intelligence reporting
======
Since its creation in 2015 at an Airbnb hackathon, Apache Superset has
matured into a leading open source BI solution.
![metrics and data shown on a computer screen][1]
They say software is eating the world, but it's equally clear that open source is taking over software.
Simply put, open source is a superior approach for building and distributing software because it provides important guarantees around how software can be discovered, tried, operated, collaborated on, and packaged. For those reasons, it is not surprising that it has taken over most of the modern data stack: Infrastructure, databases, orchestration, data processing, AI/ML, and beyond.
Looking back, the main reason why I originally created both [Apache Airflow][2] and [Apache Superset][3] while I was at Airbnb from 2014-17 is that the vendors in the data space were failing to:
* Keep up with the pace of innovation in the data ecosystem
* Give power to users who wanted to satisfy their more advanced use cases
As is often the case with open source, the capacity to integrate and extend was always at the core of how we approached the architecture of those two projects.
### Headaches with Tableau
More specifically, for Superset, the main driver to start the project at the time was the fact that Tableau (which was, at the time, our main data visualization tool) couldn't connect natively to [Apache Druid][4] and [Trino][5]/[Presto][6]. These were our data engines of choice that provided the properties and guarantees that we needed to satisfy our data use cases.
With Tableau's "Live Mode" misbehaving in intricate ways at the time (I won't get into this!), we were steered towards using Tableau Extracts. Extracts crumbled under the data volumes we had at Airbnb, creating a whole lot of challenges around non-additive metrics (think distinct user counts) and forcing us to intricately pre-compute multiple "grouping sets," which broke down some of the Tableau paradigms and confused users. Secondarily, we had a limited number of licenses for Tableau and generally had an order of magnitude more employees that wanted/needed access to our internal than our contract allowed. That's without mentioning the fact that for a cloud-native company, Tableau's Windows-centric approach at the time didn't work well for the team.
Some of the above premises have since changed, but the power of open source and the core principles on which it's built have only grown. In this blog post, I will explain why the future of business intelligence is open source.
## Benefits of open source
If I could only use a single word to describe why the time is right for organizations to adopt open source BI, the word would be _freedom_. Flowing from the principle of freedom comes a few more concrete superpowers for an organization:
* The power to customize, extend and integrate
* The power of the community
* Avoid vendor lock-in
### Extend, customize, and integrate
Airbnb wanted to integrate in-house tools like Dataportal and Minerva with a dashboarding tool to enable data democratization within their organization. Because Superset is open source and Airbnb actively contributes to the project, they could supercharge Superset with in-house components with relative ease.
On the visualization side, organizations like Nielsen create new visualizations and deploy them in their Superset environments. They're going a step further by empowering their engineers to contribute to Superset's customizability and extensibility. The Superset platform is now flexible enough so that anyone can build their [own custom visualization plugins][7], a benefit that is unmatched in the marketplace.
Many report using the rich [REST API that ships with Superset][8] within the wider community, allowing them full programmatic control over all aspects of the platform. Given that pretty much everything that users can do in Superset can be done through the API, the sky is the limit for automating processes in and around Superset.
Around the topic of integration, members from the Superset community have added support for over 30 databases ([and growing!][9]) by submitting code and documentation contributions. Because the core contributors bet on the right open source components ([SQLAlchemy][10] and Python [DB-API 2.0][11]), the Superset community both gives and receives to/from the broader Python community.
### The power of the community
Open source communities are composed of a diverse group of people who come together over a similar set of needs. This group is empowered to contribute to the common good. Vendors, on the other hand, tend to focus on their most important customers. Open source is a fundamentally different model that's much more collaborative and frictionless. As a result of this fundamentally de-centralized model, communities are very resilient to changes that vendor-led products struggle with. As contributors and organizations come and go, the community lives on!
At the core of the community are the active contributors that typically operate as a dynamic meritocracy. Network effects attract attention and talent, and communities welcome and offer guidance to newcomers because their goals are aligned. With the rise of platforms like Gitlab and Github, software is pretty unique in that engineers and developers from around the world seem to be able to come together and work collaboratively with minimal overhead. Those dynamics are fairly well understood and accepted as a disruptive paradigm shift in how people collaborate to build modern software.
![Growth in Monthly Unique Contributors][12]
Growth in Monthly Unique Contributors
Beyond the software at the core of the project, dynamic communities contribute in all sorts of ways that provide even more value. Here are some examples:
* Rich and up-to-date documentation
* Example use cases and testimonials, often in the form of blog posts
* Bug reports and bug fixes, contributing to stability and quality
* Ever-growing online knowledge bases and FAQs
* How-to videos and conference talks
* Real-time support networks of enthusiasts and experts in forums and on [chat platforms][13]
* Dynamic mailing lists where core contributors propose and debate over complex issues
* Feedback loops, ways to suggest features and influence roadmaps
### Avoid lock-in
Recently, [Atlassian acquired the proprietary BI platform Chart.io][14], started to downsize the Chart.io team, and announced their intention to shut down the platform. Their customers now have to scramble and find a new home for their analytics assets that they now have to rebuild.
![Chart.io Shutting Down][15]
Chart.io Shutting Down
This isn't a new phenomenon. Given how mature and dynamic the BI market is, consolidation has been accelerating over the past few years:
* Tableau was acquired by Salesforce
* Looker was acquired by Google Cloud
* Periscope was acquired by Sisense
* Zoomdata was acquired by Logi Analytics
While consolidation is likely to continue, these concerns don't arise when your BI platform is open source. If you're self-hosting, you are essentially immune to vendor lock-in. If you choose to partner with a commercial open source software (COSS), you should have an array of options from alternative vendors to hiring expertise in the marketplace, all the way to taking ownership and operating the software on your own.
For example, if you were using Apache Airflow service to take care of your Airflow needs, and your cloud provider decided to shut down the service, you'd be left with a set of viable options:
* Select and migrate to another service provider in the space, such as Apache Airflow specialist [Astronomer][16].
* Hire or consult Airflow talent that can help you take control. The community has fostered a large number of professionals who know and love Airflow and can help your organization.
* Learn and act. That is, take control and tap into the community's amazing resources to run the software on your own (Docker, Helm, k8s operator, and so on.)
Even at [Preset][17], where we offer a cloud-hosted version of Superset, we don't fork the Superset code and instead run the same Superset that's available to everyone. In the Preset cloud, you can freely import and export data sources, charts, and dashboards. This is not unique to Preset. Many vendors understand that "no lock-in!" is integral to their value proposition and are incentivized to provide clear guarantees around this.
## Open source for your data
Open source is disruptive in the best of ways, providing freedom, and a set of guarantees that really matter when it comes to adopting software. These guarantees fully apply when it comes to business intelligence. In terms of business intelligence, Apache Superset has matured to a level where it's a compelling choice over any proprietary solution. Since its creation in 2015 at an Airbnb hackathon, the project has come a very long way indeed. Try it yourself to discover a combination of features and guarantees unique to open source BI. To learn more, visit and [join our growing community][18].
In this article, I review some of the top open source business intelligence (BI) and reporting...
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/4/business-intelligence-open-source
作者:[Maxime Beauchemin][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/mistercrunch
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/metrics_data_dashboard_system_computer_analytics.png?itok=oxAeIEI- (metrics and data shown on a computer screen)
[2]: https://airflow.apache.org/
[3]: https://superset.apache.org/
[4]: https://druid.apache.org/
[5]: https://trino.io/
[6]: https://prestodb.io/
[7]: https://preset.io/blog/2020-07-02-hello-world/
[8]: https://superset.apache.org/docs/rest-api/
[9]: https://superset.apache.org/docs/databases/installing-database-drivers
[10]: https://www.sqlalchemy.org/
[11]: https://www.python.org/dev/peps/pep-0249/
[12]: https://opensource.com/sites/default/files/uniquecontributors.png
[13]: https://opensource.com/article/20/7/mattermost
[14]: https://www.atlassian.com/blog/announcements/atlassian-acquires-chartio
[15]: https://opensource.com/sites/default/files/chartio.jpg
[16]: https://www.astronomer.io/
[17]: https://preset.io/
[18]: https://superset.apache.org/community/

View File

@@ -1,174 +0,0 @@
[#]: subject: (Protect external storage with this Linux encryption system)
[#]: via: (https://opensource.com/article/21/3/encryption-luks)
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
Protect external storage with this Linux encryption system
======
Use Linux Unified Key Setup to encrypt your thumb drives, external hard
drives, and other storage from prying eyes.
![A keyboard with privacy written on it.][1]
Many people consider hard drives secure because they physically own them. It's difficult to read the data on a hard drive that you don't have, and many people think that protecting their computer with a passphrase makes the data on the drive unreadable.
This isn't always the case, partly because, in some cases, a passphrase serves only to unlock a user session. In other words, you can power on a computer, but because you don't have its passphrase, you can't get to the desktop, and so you have no way to open files to look at them.
The problem, as many a computer technician understands, is that hard drives can be extracted from computers, and some drives are already external by design (USB thumb drives, for instance), so they can be attached to any computer for full access to the data on them. You don't have to physically separate a drive from its computer host for this trick to work, either. Computers can be [booted from a portable boot drive][2], which separates a drive from its host operating system and turns it into, virtually, an external drive available for reading.
The answer is to place the data on a drive into a digital vault that can't be opened without information that only you have access to.
Linux Unified Key Setup ([LUKS][3]) is a disk-encryption system. It provides a generic key store (and associated metadata and recovery aids) in a dedicated area on a disk with the ability to use multiple passphrases (or key files) to unlock a stored key. It's designed to be flexible and can even store metadata externally so that it can be integrated with other tools. The result is full-drive encryption, so you can store all of your data confident that it's safe—even if your drive is separated, either physically or through software, from your computer.
### Encrypting during installation
The easiest way to implement full-drive encryption is to select the option during installation. Most modern Linux distributions offer this as an option, so it's usually a trivial process.
![Encrypt during installation][4]
(Seth Kenlon, [CC BY-SA 4.0][5])
This establishes everything you need: an encrypted drive requiring a passphrase before your system can boot. If the drive is extracted from your computer or accessed from another operating system running on your computer, the drive must be decrypted by LUKS before it can be mounted.
### Encrypting external drives
It's not common to separate an internal hard drive from its computer, but external drives are designed to travel. As technology gets smaller and smaller, it's easier to put a portable drive on your keychain and carry it around with you every day. The obvious danger, however, is that these are also pretty easy to misplace. I've found abandoned drives in the USB ports of hotel lobby computers, business center printers, classrooms, and even a laundromat. Most of these didn't include personal information, but it's an easy mistake to make.
You can mitigate against misplacing important data by encrypting your external drives.
LUKS and its frontend `cryptsetup` provide a way to do this on Linux. As Linux does during installation, you can encrypt the entire drive so that it requires a passphrase to mount it.
### How to encrypt an external drive with LUKS
First, you need an empty external drive (or a drive with contents you're willing to erase). This process overwrites all the data on a drive, so if you have data that you want to keep on the drive, _back it up first_.
#### 1\. Find your drive
I used a small USB thumb drive. To protect you from accidentally erasing data, the drive referenced in this article is located at the imaginary location `/dev/sdX`. Attach your drive and find its location:
```
$ lsblk
sda    8:0    0 111.8G  0 disk
sda1   8:1    0 111.8G  0 part /
sdb    8:112  1  57.6G  0 disk
sdb1   8:113  1  57.6G  0 part /mydrive
sdX    8:128  1   1.8G  0 disk
sdX1   8:129  1   1.8G  0 part
```
I know that my demo drive is located at `/dev/sdX` because I recognize its size (1.8GB), and it's also the last drive I attached (with `sda` being the first, `sdb` the second, `sdc` the third, and so on). The `/dev/sdX1` designator means the drive has 1 partition.
If you're unsure, remove your drive, look at the output of `lsblk`, and then attach your drive and look at `lsblk` again.
Make sure you identify the correct drive because encrypting it overwrites _everything on it_. My drive is not empty, but it contains copies of documents I have copies of elsewhere, so losing this data isn't significant to me.
#### 2\. Clear the drive
To proceed, destroy the drive's partition table by overwriting the drive's head with zeros:
```
`$ sudo dd if=/dev/zero of=/dev/sdX count=4096`
```
This step isn't strictly necessary, but I like to start with a clean slate.
#### 3\. Format your drive for LUKS
The `cryptsetup` command is a frontend for managing LUKS volumes. The `luksFormat` subcommand creates a sort of LUKS vault that's password-protected and can house a secured filesystem.
When you create a LUKS partition, you're warned about overwriting data and then prompted to create a passphrase for your drive:
```
$ sudo cryptsetup luksFormat /dev/sdX
WARNING!
========
This will overwrite data on /dev/sdX irrevocably.
Are you sure? (Type uppercase yes): YES
Enter passphrase:
Verify passphrase:
```
#### 4\. Open the LUKS volume
Now you have a fully encrypted vault on your drive. Prying eyes, including your own right now, are kept out of this LUKS partition. So to use it, you must open it with your passphrase. Open the LUKS vault with `cryptsetup open` along with the device location (`/dev/sdX`, in my example) and an arbitrary name for your opened vault:
```
`$ cryptsetup open /dev/sdX vaultdrive`
```
I use `vaultdrive` in this example, but you can name your vault anything you want, and you can give it a different name every time you open it.
LUKS volumes are opened in a special device location called `/dev/mapper`. You can list the files there to check that your vault was added:
```
$ ls /dev/mapper
control  vaultdrive
```
You can close a LUKS volume at any time using the `close` subcommand:
```
`$ cryptsetup close vaultdrive`
```
This removes the volume from `/dev/mapper`.
#### 5\. Create a filesystem
Now that you have your LUKS volume decrypted and open, you must create a filesystem there to store data in it. In my example, I use XFS, but you can use ext4 or JFS or any filesystem you want:
```
`$ sudo mkfs.xfs -f -L myvault /dev/mapper/vaultdrive`
```
### Mount and unmount a LUKS volume
You can mount a LUKS volume from a terminal with the `mount` command. Assume you have a directory called `/mnt/hd` and want to mount your LUKS volume there:
```
$ sudo cryptsetup open /dev/sdX vaultdrive
$ sudo mount /dev/mapper/vaultdrive /mnt/hd
```
LUKS also integrates into popular Linux desktops. For instance, when I attach an encrypted drive to my workstation running KDE or my laptop running GNOME, my file manager prompts me for a passphrase before it mounts the drive.
![LUKS requesting passcode to mount drive][6]
(Seth Kenlon, [CC BY-SA 4.0][5])
### Encryption is protection
Linux makes encryption easier than ever. It's so easy, in fact, that it's nearly unnoticeable. The next time you [format an external drive for Linux][7], consider using LUKS first. It integrates seamlessly with your Linux desktop and protects your important data from accidental exposure.
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/3/encryption-luks
作者:[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/privacy_keyboard_security.jpg?itok=vZ9jFdK_ (A keyboard with privacy written on it.)
[2]: https://opensource.com/article/19/6/linux-distros-to-try
[3]: https://gitlab.com/cryptsetup/cryptsetup/blob/master/README.md
[4]: https://opensource.com/sites/default/files/uploads/centos8-install-encrypt.jpg (Encrypt during installation)
[5]: https://creativecommons.org/licenses/by-sa/4.0/
[6]: https://opensource.com/sites/default/files/uploads/luks-mount-gui.png (LUKS requesting passcode to mount drive)
[7]: https://opensource.com/article/18/11/partition-format-drive-linux

View File

@@ -1,274 +0,0 @@
[#]: subject: (Stream event data with this open source tool)
[#]: via: (https://opensource.com/article/21/4/event-streaming-rudderstack)
[#]: author: (Amey Varangaonkar https://opensource.com/users/ameypv)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
Stream event data with this open source tool
======
Route real-time events from web, mobile, and server-side app sources to
help build your customer data lake on your data warehouse.
![Net catching 1s and 0s or data in the clouds][1]
In my [previous article][2], I introduced [RudderStack][3], an open source, warehouse-first customer data pipeline. In this article, I demonstrate how easy Rudderstack makes it to set up and use event streams.
An event stream is a pipeline between a source you define and a destination of your choice. Rudderstack provides you with SDKs and plugins to help you ingest event data from your website, mobile apps, and server-side sources — including JavaScript, Gatsby, Android, iOS, Unity, ReactNative, Node.js, and many more. Similarly, Rudderstack's **Event Stream** module features over 80 destination and warehouse integrations, including Firebase, Google Analytics, Salesforce, Zendesk, Snowflake, BigQuery, RedShift, and more, making it easy to send event data to downstream tools that can use it as well as build a customer data lake on a data warehouse for analytical use cases.
This tutorial shows how to track and route events using RudderStack.
### How to set up an event stream
Before you get started, make sure you understand these terms used in this tutorial:
* **Source**: A source refers to a tool or a platform from which RudderStack ingests your event data. Your website, mobile app, or your back-end server are common examples of sources.
* **Destination**: A destination refers to a tool that receives your event data from RudderStack. These destination tools can then use this data for your activation use cases. Tools like Google Analytics, Salesforce, and HubSpot are common examples of destinations.
The steps for setting up an event stream in RudderStack open source are:
1. Instrumenting an event stream source
2. Configuring a warehouse destination
3. Configuring a tool destination
4. Sending events to verify the event stream
### Step 1: Instrument an event stream source
To set up an event stream source in RudderStack:
1. Log into your [RudderStack dashboard][4]. If you don't have a RudderStack account, please sign up. You can use the RudderStack open source control plane to [set up your event streams][5].
RudderStack's hosted control plane is an option to manage your event stream configurations. It is completely free, requires no setup, and has some more advanced features than the open source control plane.
2. Once you've logged into RudderStack, you should see the following dashboard:
![RudderStack dashboard][6]
(Gavin Johnson, [CC BY-SA 4.0][7])
**Note:** Make sure to save the **Data Plane URL**. It is required in your RudderStack JavaScript SDK snippet to track events from your website.
3. To instrument the source, click **Add Source**. Optionally, you can also select the **Directory** option on the left navigation bar, and select **Event Streams** under **Sources**. This tutorial will set up a simple **JavaScript** source that allows you to track events from your website.
![RudderStack event streams dashboard][8]
(Gavin Johnson, [CC BY-SA 4.0][7])
4. Assign a name to your source, and click **Next**.
![RudderStack Source Name][9]
(Gavin Johnson, [CC BY-SA 4.0][7])
5. That's it! Your event source is now configured.
![RudderStack source write key][10]
(Gavin Johnson, [CC BY-SA 4.0][7])
**Note:** Save the source **Write Key**. Your RudderStack JavaScript SDK snippet requires it to track events from your website.
Now you need to install the RudderStack JavaScript SDK on your website. To do this, you need to place either the minified or non-minified version of the snippet with your **Data Plane URL** and source **Write Key** in your website's `<head>` section. Consult the docs for information on how to [install and use the RudderStack JavaScript SDK][11].
### Step 2: Configure a warehouse destination
**Important**: Before you configure your data warehouse as a destination in RudderStack, you need to set up a new project in your warehouse and create a RudderStack user role with the relevant permissions. The docs provide [detailed, step-by-step instructions][12] on how to do this for the warehouse of your choice.
This tutorial sets up a Google BigQuery warehouse destination. You don't have to configure a warehouse destination, but I recommend it. The docs provide [instructions on setting up][13] a Google BigQuery project and a service account with the required permissions.
Then configure BigQuery as a warehouse destination in RudderStack by following these steps:
1. On the left navigation bar, click on **Directory**, and then click on **Google BigQuery** from the list of destinations:
![RudderStack destination options][14]
(Gavin Johnson, [CC BY-SA 4.0][7])
2. Assign a name to your destination, and click on **Next**.
![RudderStack naming the destination][15]
(Gavin Johnson, [CC BY-SA 4.0][7])
3. Choose which source you want to use to send the events to your destination. Select the source that you created in the previous section. Then, click on **Next**.
![RudderStack selecting data source][16]
(Gavin Johnson, [CC BY-SA 4.0][7])
4. Specify the required connection credentials. For this destination, enter the **BigQuery Project ID** and the **staging bucket name**; information on [how to get this information][17] is in the docs.
![RudderStack connection credentials][18]
(Gavin Johnson, [CC BY-SA 4.0][7])
5. Copy the contents of the private JSON file you created, as [the docs][19] explain.
That's it! You have configured your BigQuery warehouse as a destination in RudderStack. Once you start sending events from your source (a website in this case), RudderStack will automatically route them into your BigQuery and build your identity graph there as well.
### Step 3: Configure a tool destination
Once you've added a source, follow these steps to configure a destination in the RudderStack dashboard:
1. To add a new destination, click on the **Add Destination** button as shown:
![RudderStack adding the destination][20]
(Gavin Johnson, [CC BY-SA 4.0][7])
**Note:** If you have configured a destination before, use the **Connect Destinations** option to connect it to any source.
2. RudderStack supports over 80 destinations to which you can send your event data. Choose your preferred destination platform from the list. This example configures **Google Analytics** as a destination.
![RudderStack selecting destination platform][21]
(Gavin Johnson, [CC BY-SA 4.0][7])
3. Add a name to your destination, and click **Next**.
![RudderStack naming the destination][22]
(Gavin Johnson, [CC BY-SA 4.0][7])
4. Next, choose the preferred source. If you're following along with this tutorial, choose the source you configured above.
![RudderStack choosing source][23]
(Gavin Johnson, [CC BY-SA 4.0][7])
5. In this step, you must add the relevant **Connection Settings**. Enter the **Tracking ID** for this destination (Google Analytics). You can also configure other optional settings per your requirements. Once you've added the required settings, click **Next**.
![RudderStack connection settings][24]
(Gavin Johnson, [CC BY-SA 4.0][7])
**Note**: RudderStack also gives you the option of transforming the events before sending them to your destination. Read more about [user transformations][25] in RudderStack in the docs.
6. That's it! The destination is now configured. You should now see it connected to your source.
![RudderStack connection configured][26]
(Gavin Johnson, [CC BY-SA 4.0][7])
### Step 4: Send test events to verify the event stream
This tutorial set up a JavaScript source to track events from your website. Once you have placed the JavaScript code snippet in your website's `<head>` section, RudderStack will automatically track and collect user events from the website in real time.
However, to quickly test if your event stream is set up correctly, you can send some test events. To do so, follow these steps:
**Note**: Before you get started, you will need to clone the [rudder-server][27] repo and have a RudderStack server installed in your environment. Follow [this tutorial][28] to set up a RudderStack server.
1. Make sure you have set up a source and destination by following the steps in the previous sections and have your **Data Plane URL** and source **Write Key** available.
2. Start the RudderStack server.
3. The **rudder-server** repo includes a shell script that generates test events. Get the source **Write Key** from step 2, and run the following command:
```
`./scripts/generate-event <YOUR_WRITE_KEY> <YOUR_DATA_PLANE_URL>/v1/batch`
```
![RudderStack event testing code][29]
(Gavin Johnson, [CC BY-SA 4.0][7])
4. To check if the test events are delivered, go to your Google Analytics dashboard, navigate to **Realtime** under Reports, and click **Events**.
**Note**: Make sure you check the events associated with the same Tracking ID you provided while instrumenting the destination.
You should now be able to see the test event received in Google Analytics and BigQuery.
![RudderStack event test][30]
(Gavin Johnson, [CC BY-SA 4.0][7])
If you come across any issues while setting up or configuring RudderStack open source, join our [Slack][31] and start a conversation in our #open-source channel. We will be happy to help.
If you want to try RudderStack but don't want to host your own, sign up for our free, hosted offering, [RudderStack Cloud Free][32]. Explore our open source repos on [GitHub][33], subscribe to [our blog][34], and follow us on our socials: [Twitter][35], [LinkedIn][36], [dev.to][37], [Medium][38], and [YouTube][39].
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/4/event-streaming-rudderstack
作者:[Amey Varangaonkar][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/ameypv
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/data_analytics_cloud.png?itok=eE4uIoaB (Net catching 1s and 0s or data in the clouds)
[2]: https://opensource.com/article/21/3/rudderstack-customer-data-platform
[3]: https://rudderstack.com/
[4]: https://app.rudderstack.com/
[5]: https://docs.rudderstack.com/how-to-guides/rudderstack-config-generator
[6]: https://opensource.com/sites/default/files/uploads/rudderstack_dashboard.png (RudderStack dashboard)
[7]: https://creativecommons.org/licenses/by-sa/4.0/
[8]: https://opensource.com/sites/default/files/uploads/rudderstack_eventstreamsdash.png (RudderStack event streams dashboard)
[9]: https://opensource.com/sites/default/files/uploads/rudderstack_namesource.png (RudderStack Source Name)
[10]: https://opensource.com/sites/default/files/uploads/rudderstack_writekey.png (RudderStack Source Name)
[11]: https://docs.rudderstack.com/rudderstack-sdk-integration-guides/rudderstack-javascript-sdk
[12]: https://docs.rudderstack.com/data-warehouse-integrations
[13]: https://docs.rudderstack.com/data-warehouse-integrations/google-bigquery
[14]: https://opensource.com/sites/default/files/uploads/rudderstack_destinations.png (RudderStack destination options)
[15]: https://opensource.com/sites/default/files/uploads/rudderstack_namedestination.png (RudderStack naming the destination)
[16]: https://opensource.com/sites/default/files/uploads/rudderstack_adddestination.png (RudderStack selecting data source)
[17]: https://docs.rudderstack.com/data-warehouse-integrations/google-bigquery#setting-up-google-bigquery
[18]: https://opensource.com/sites/default/files/uploads/rudderstack_connectioncredentials.png (RudderStack connection credentials)
[19]: https://docs.rudderstack.com/data-warehouse-integrations/google-bigquery#setting-up-the-service-account-for-rudderstack
[20]: https://opensource.com/sites/default/files/uploads/rudderstack_addnewdestination.png (RudderStack adding the destination)
[21]: https://opensource.com/sites/default/files/uploads/rudderstack_googleanalyticsdestination.png (RudderStack selecting destination platform)
[22]: https://opensource.com/sites/default/files/uploads/rudderstack_namenewdestination.png (RudderStack naming the destination)
[23]: https://opensource.com/sites/default/files/uploads/rudderstack_choosepreferredsource.png (RudderStack choosing source)
[24]: https://opensource.com/sites/default/files/uploads/rudderstack_connectionsettings.png (RudderStack connection settings)
[25]: https://docs.rudderstack.com/adding-a-new-user-transformation-in-rudderstack
[26]: https://opensource.com/sites/default/files/uploads/rudderstack_destinationconfigured.png (RudderStack connection configured)
[27]: https://github.com/rudderlabs/rudder-server
[28]: https://docs.rudderstack.com/installing-and-setting-up-rudderstack/docker
[29]: https://opensource.com/sites/default/files/uploads/rudderstack_testevents.jpg (RudderStack event testing code)
[30]: https://opensource.com/sites/default/files/uploads/rudderstack_testeventoutput.png (RudderStack event test)
[31]: https://resources.rudderstack.com/join-rudderstack-slack
[32]: https://app.rudderlabs.com/signup?type=freetrial
[33]: https://github.com/rudderlabs
[34]: https://rudderstack.com/blog/
[35]: https://twitter.com/RudderStack
[36]: https://www.linkedin.com/company/rudderlabs/
[37]: https://dev.to/rudderstack
[38]: https://rudderstack.medium.com/
[39]: https://www.youtube.com/channel/UCgV-B77bV_-LOmKYHw8jvBw

View File

@@ -1,49 +0,0 @@
[#]: subject: (Why Crate.io has returned to its pure open source roots)
[#]: via: (https://opensource.com/article/21/4/crate-open-source)
[#]: author: (Bernd Dorn https://opensource.com/users/bernd-dorn)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
Why Crate.io has returned to its pure open source roots
======
CrateDB's renewed commitment to open source aligns with both our best
ideals and what's best for our business.
![Open source stars.][1]
The headline benefits of open source are widely known and well-articulated. Open source technologies provide enterprise-level scalability, performance, security, and reliability. Trust is there, and it's deserved. But what's less celebrated, other than by die-hard open source adherents, are the inner workings of the everyday community contributions building those macro benefits at the atomic level. For those offering open source technologies, it is the community's constant user-driven testing and hardening that forges those technologies into robust and proven solutions. Those contributions don't show up on the balance sheet, but they can be absolutely formative to an enterprise's health and success.
In 2013, I co-founded [Crate.io][2] with open source ideals and my belief in the power of the community. As a startup intent on bringing the simplicity and strength of open source to the realm of advanced SQL databases that could handle the growing volume of Internet of Things (IoT) and Industrial IoT data, we rooted our CrateDB database in 100% open source component technologies. And we were sure to play our role as active contributors to those technologies and nurtured our own community of CrateDB developers.
In 2017, Crate began exploring an open core business model, and soon after, I took a few years away from the company. In 2019, Crate began to offer a CrateDB Free Edition with a strict three-node limit and stopped building and distributing packages for CrateDB Community Edition (the open source code could still be downloaded). This move focused the company more heavily on a paid open core enterprise edition that added some proprietary features. From a sales perspective, the idea was to spur community users to convert to paying customers. However, this strategy ended up being a fundamental misunderstanding of the user base. The result was a marked decline in user engagement and the strength of our valuable community while failing to convert much of anyone.
When I returned to Crate towards the end of 2020 as CTO, I made it my priority to bring back a commitment to pure open source. This sparked a rich conversation between competing viewpoints within our organization. The key to winning over my more revenue-minded colleagues was to explain that community users are completely different in nature from our enterprise customers and offer our business a different kind of support. Furthermore, forcing them away does nothing positive. Our open source community user base contributes crucial influence and experience that improves our technologies very effectively. Their support is invaluable and irreplaceable. Without them, CrateDB isn't nearly as compelling or as enterprise-ready a product.
Ultimately, it was our investors that weighed in and championed Crate's once and future commitment to pure open source. Our investors even helped us abandon considerations towards other licensing models such as the Business Source License by favoring the [Apache License 2.0][3] we now utilize, pressing for the fully open source permissions it offers.
Our recent [4.5 release][4] of CrateDB completes this full circle to our open source roots. I couldn't be prouder to say that our business is rededicated to building our community and openly welcomes all contributors as we work hand-in-hand to push CrateDB toward its full potential as a distributed SQL database for machine data.
I also need to mention the recent decision by [Elastic to discontinue its longstanding commitment to open source][5], as it offers a stark juxtaposition to ours. CrateDB has used open source Elasticsearch from the very beginning. But more than that, open source Elasticsearch was a formative inspiration to Crate's founders, especially me. Our drive to serve as contributing citizens in that community was born out of our work operating some of Europe's largest Elasticsearch deployments. That team and I later created Crate with Elasticsearch as our clearest example of why upholding open source ideals results in powerful technologies.
Our renewed commitment to open source elegantly aligns with both our best ideals and what's best for our business. The activity of a robust and inclusive open source community is the vital pulse of our product. It's our hope to provide an example of what dedication to pure open source can truly accomplish.
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/4/crate-open-source
作者:[Bernd Dorn][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/bernd-dorn
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/osdc_520x292_opensourcestars.png?itok=hnrMETFh (Open source stars.)
[2]: https://crate.io/
[3]: https://www.apache.org/licenses/LICENSE-2.0
[4]: https://crate.io/products/cratedb/
[5]: https://www.elastic.co/blog/licensing-change

View File

@@ -1,472 +0,0 @@
[#]: subject: (Make Conway's Game of Life in WebAssembly)
[#]: via: (https://opensource.com/article/21/4/game-life-simulation-webassembly)
[#]: author: (Mohammed Saud https://opensource.com/users/saud)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
Make Conway's Game of Life in WebAssembly
======
WebAssembly is a good option for computationally expensive tasks due to
its predefined execution environment and memory granularity.
![Woman sitting in front of her computer][1]
Conway's [Game of Life][2] is a popular programming exercise to create a [cellular automaton][3], a system that consists of an infinite grid of cells. You don't play the game in the traditional sense; in fact, it is sometimes referred to as a game for zero players.
Once you start the Game of Life, the game plays itself to multiply and sustain "life." In the game, digital cells representing lifeforms are allowed to change states as defined by a set of rules. When the rules are applied to cells through multiple iterations, they exhibit complex behavior and interesting patterns.
The Game of Life simulation is a very good candidate for a WebAssembly implementation because of how computationally expensive it can be; every cell's state in the entire grid must be calculated for every iteration. WebAssembly excels at computationally expensive tasks due to its predefined execution environment and memory granularity, among many other features.
### Compiling to WebAssembly
Although it's possible to write WebAssembly by hand, it is very unintuitive and error-prone as complexity increases. Most importantly, it's not intended to be written that way. It would be the equivalent of manually writing [assembly language][4] instructions.
Here's a simple WebAssembly function to add two numbers:
```
(func $Add (param $0 i32) (param $1 i32) (result i32)
    local.get $0
    local.get $1
    i32.add
)
```
It is possible to compile WebAssembly modules using many existing languages, including C, C++, Rust, Go, and even interpreted languages like Lua and Python. This [list][5] is only growing.
One of the problems with using existing languages is that WebAssembly does not have much of a runtime. It does not know what it means to [free a pointer][6] or what a [closure][7] is. All these language-specific runtimes have to be included in the resulting WebAssembly binaries. Runtime size varies by language, but it has an impact on module size and execution time.
### AssemblyScript
[AssemblyScript][8] is one language that is trying to overcome some of these challenges with a different approach. AssemblyScript is designed specifically for WebAssembly, with a focus on providing low-level control, producing smaller binaries, and reducing the runtime overhead.
AssemblyScript uses a strictly typed variant of [TypeScript][9], a superset of JavaScript. Developers familiar with TypeScript do not have to go through the trouble of learning an entirely new language.
### Getting started
The AssemblyScript compiler can easily be installed through [Node,js][10]. Start by initializing a new project in an empty directory:
```
npm init
npm install --save-dev assemblyscript
```
If you don't have Node installed locally, you can play around with AssemblyScript on your browser using the nifty [WebAssembly Studio][11] application.
AssemblyScript comes with `asinit`, which should be installed when you run the installation command above. It is a helpful utility to quickly set up an AssemblyScript project with the recommended directory structure and configuration files:
```
`npx asinit .`
```
The newly created `assembly` directory will contain all the AssemblyScript code, a simple example function in `assembly/index.ts`, and the `asbuild` command inside `package.json`. `asbuild`, which compiles the code into WebAssembly binaries.
When you run `npm run asbuild` to compile the code, it creates files inside `build`. The `.wasm` files are the generated WebAssembly modules. The `.wat` files are the modules in text format and are generally used for debugging and inspection.
You have to do a little bit of work to get the binaries to run on a browser.
First, create a simple HTML file, `index.html`:
```
&lt;[html][12]&gt;
    &lt;[head][13]&gt;
        &lt;[meta][14] charset=utf-8&gt;
        &lt;[title][15]&gt;Game of life&lt;/[title][15]&gt;
    &lt;/[head][13]&gt;
   
    &lt;[body][16]&gt;
        &lt;[script][17] src='./index.js'&gt;&lt;/[script][17]&gt;
    &lt;/[body][16]&gt;
&lt;/[html][12]&gt;
```
Next, replace the contents of `index.js` with the code snippet below to load the WebAssembly modules:
```
const runWasm = async () =&gt; {
  const module = await WebAssembly.instantiateStreaming(fetch('./build/optimized.wasm'));
  const exports = module.instance.exports;
  console.log('Sum = ', exports.add(20, 22));
};
runWasm();
```
This `fetches` the binary and passes it to `WebAssembly.instantiateStreaming`, the browser API that compiles a module into a ready-to-use instance. This is an asynchronous operation, so it is run inside an async function so that await can be used to wait for it to finish compiling.
The `module.instance.exports` object contains all the functions exported by AssemblyScript. Use the example function in `assembly/index.ts` and log the result.
You will need a simple development server to host these files. There are a lot of options listed in this [gist][18]. I used [node-static][19]:
```
npm install -g node-static
static
```
You can view the result by pointing your browser to `localhost:8080` and opening the console.
![console output][20]
(Mohammed Saud, [CC BY-SA 4.0][21])
### Drawing to a canvas
You will be drawing all the cells onto a `<canvas>` element:
```
&lt;[body][16]&gt;
    &lt;[canvas][22] id=canvas&gt;&lt;/[canvas][22]&gt;
    ...
&lt;/[body][16]&gt;
```
Add some CSS:
```
&lt;[head][13]&gt;
    ...
    &lt;[style][23] type=text/css&gt;
    body {
      background: #ccc;
    }
    canvas {
      display: block;
      padding: 0;
      margin: auto;
      width: 40%;
      image-rendering: pixelated;
      image-rendering: crisp-edges;
    }
    &lt;/[style][23]&gt;
&lt;/[head][13]&gt;
```
The `image-rendering` styles are used to prevent the canvas from smoothing and blurring out pixelated images.
You will need a canvas drawing context in `index.js`:
```
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
```
There are many functions in the [Canvas API][24] that you could use for drawing—but you need to draw using WebAssembly, not JavaScript.
Remember that WebAssembly does NOT have access to the browser APIs that JavaScript has, and any call that needs to be made should be interfaced through JavaScript. This also means that your WebAssembly module will run the fastest if there is as little communication with JavaScript as possible.
One method is to create [ImageData][25] (a data type for the underlying pixel data of a canvas), fill it up with the WebAssembly module's memory, and draw it on the canvas. This way, if the memory buffer is updated inside WebAssembly, it will be immediately available to the `ImageData`.
Define the pixel count of the canvas and create an `ImageData` object:
```
const WIDTH = 10, HEIGHT = 10;
const runWasm = async () =&gt; {
...
canvas.width = WIDTH;
canvas.height = HEIGHT;
const ctx = canvas.getContext('2d');
const memoryBuffer = exports.memory.buffer;
const memoryArray = new Uint8ClampedArray(memoryBuffer)
const imageData = ctx.createImageData(WIDTH, HEIGHT);
imageData.data.set(memoryArray.slice(0, WIDTH * HEIGHT * 4));
ctx.putImageData(imageData, 0, 0);
```
The memory of a WebAssembly module is provided in `exports.memory.buffer` as an [ArrayBuffer][26]. You need to use it as an array of 8-bit unsigned integers or `Uint8ClampedArray`. Now you can fill up the module's memory with some pixels. In `assembly/index.ts`, you first need to grow the available memory:
```
`memory.grow(1);`
```
WebAssembly does not have access to memory by default and needs to request it from the browser using the `memory.grow` function. Memory grows in chunks of 64Kb, and the number of required chunks can be specified when calling it. You will not need more than one chunk for now.
Keep in mind that memory can be requested multiple times, whenever needed, and once acquired, memory cannot be freed or given back to the browser.
Writing to the memory:
```
`store<u32>(0, 0xff101010);`
```
A pixel is represented by 32 bits, with the RGBA values taking up 8 bits each. Here, RGBA is defined in reverse—ABGR—because WebAssembly is [little-endian][27].
The `store` function stores the value `0xff101010` at index `0`, taking up 32 bits. The alpha value is `0xff` so that the pixel is fully opaque.
![Byte order for a pixel's color][28]
(Mohammed Saud, [CC BY-SA 4.0][21])
Build the module again with `npm run asbuild` before refreshing the page to see your first pixel on the top-left of the canvas.
### Implementing rules
Let's review the rules. The [Game of Life Wikipedia page][29] summarizes them nicely:
1. Any live cell with fewer than two live neighbors dies, as if by underpopulation.
2. Any live cell with two or three live neighbors lives on to the next generation.
3. Any live cell with more than three live neighbors dies, as if by overpopulation.
4. Any dead cell with exactly three live neighbors becomes a live cell, as if by reproduction.
You need to iterate through all the rows, implementing these rules on each cell. You do not know the width and height of the grid, so write a little function to initialize the WebAssembly module with this information:
```
let universe_width: u32;
let universe_height: u32;
let alive_color: u32;
let dead_color: u32;
let chunk_offset: u32;
export function init(width: u32, height: u32): void {
  universe_width = width;
  universe_height = height;
  chunk_offset = width * height * 4;
  alive_color = 0xff101010;
  dead_color = 0xffefefef;
}
```
Now you can use this function in `index.js` to provide data to the module:
```
`exports.init(WIDTH, HEIGHT);`
```
Next, write an `update` function to iterate over all the cells, count the number of active neighbors for each, and set the current cell's state accordingly:
```
export function update(): void {
  for (let x: u32 = 0; x &lt; universe_width; x++) {
    for (let y: u32 = 0; y &lt; universe_height; y++) {
      const neighbours = countNeighbours(x, y);
      if (neighbours &lt; 2) {
        // less than 2 neighbours, cell is no longer alive
        setCell(x, y, dead_color);
      } else if (neighbours == 3) {
        // cell will be alive
        setCell(x, y, alive_color);
      } else if (neighbours &gt; 3) {
        // cell dies due to overpopulation
        setCell(x, y, dead_color);
      }
    }
  }
  copyToPrimary();
}
```
You have two copies of cell arrays, one representing the current state and the other for calculating and temporarily storing the next state. After the calculation is done, the second array is copied to the first for rendering.
The rules are fairly straightforward, but the `countNeighbours()` function looks interesting. Take a closer look:
```
function countNeighbours(x: u32, y: u32): u32 {
  let neighbours = 0;
  const max_x = universe_width - 1;
  const max_y = universe_height - 1;
  const y_above = y == 0 ? max_y : y - 1;
  const y_below = y == max_y ? 0 : y + 1;
  const x_left = x == 0 ? max_x : x - 1;
  const x_right = x == max_x ? 0 : x + 1;
  // top left
  if(getCell(x_left, y_above) == alive_color) {
    neighbours++;
  }
  // top
  if(getCell(x, y_above) == alive_color) {
    neighbours++;
  }
  // top right
  if(getCell(x_right, y_above) == alive_color) {
    neighbours++;
  }
  ...
  return neighbours;
}
```
![Coordinates of a cell's neighbors][30]
(Mohammed Saud, [CC BY-SA 4.0][21])
Every cell has eight neighbors, and you can check if each one is in the `alive_color` state. The important situation handled here is if a cell is exactly on the edge of the grid. Cellular automata are generally assumed to be on an infinite space, but since infinitely large displays haven't been invented yet, stick to warping at the edges. This means when a cell goes off the top, it comes back in its corresponding position on the bottom. This is commonly known as [toroidal space][31].
The `getCell` and `setCell` functions are wrappers to the `store` and `load` functions to make it easier to interact with memory using 2D coordinates:
```
@inline
function getCell(x: u32, y: u32): u32 {
  return load&lt;u32&gt;((x + y * universe_width) &lt;&lt; 2);
}
@inline
function setCell(x: u32, y: u32, val: u32): void {
  store&lt;u32&gt;(((x + y * universe_width) &lt;&lt; 2) + chunk_offset, val);
}
function copyToPrimary(): void {
  memory.copy(0, chunk_offset, chunk_offset);
}
```
The `@inline` is an [annotation][32] that requests that the compiler convert calls to the function with the function definition itself.
Call the update function on every iteration from `index.js` and render the image data from the module memory:
```
const FPS = 5;
const runWasm = async () =&gt; {
  ...
  const step = () =&gt; {
    exports.update();
 
    imageData.data.set(memoryArray.slice(0, WIDTH * HEIGHT * 4));
    ctx.putImageData(imageData, 0, 0);
 
    setTimeout(step, 1000 / FPS);
  };
  step();
```
At this point, if you compile the module and load the page, it shows nothing. The code works fine, but since you don't have any living cells initially, there are no new cells coming up.
Create a new function to randomly add cells during initialization:
```
function fillUniverse(): void {
  for (let x: u32 = 0; x &lt; universe_width; x++) {
    for (let y: u32 = 0; y &lt; universe_height; y++) {
      setCell(x, y, Math.random() &gt; 0.5 ? alive_color : dead_color);
    }
  }
  copyToPrimary();
}
export function init(width: u32, height: u32): void {
  ...
  fillUniverse();
```
Since `Math.random` is used to determine the initial state of a cell, the WebAssembly module needs a seed function to derive a random number from.
AssemblyScript provides a convenient [module loader][33] that does this and a lot more, like wrapping the browser APIs for module loading and providing functions for more fine-grained memory control. You will not be using it here since it abstracts away many details that would otherwise help in learning the inner workings of WebAssembly, so pass in a seed function instead:
```
  const importObject = {
    env: {
      seed: Date.now,
      abort: () =&gt; console.log('aborting!')
    }
  };
  const module = await WebAssembly.instantiateStreaming(fetch('./build/optimized.wasm'), importObject);
```
`instantiateStreaming` can be called with an optional second parameter, an object that exposes JavaScript functions to WebAssembly modules. Here, use `Date.now` as the seed to generate random numbers.
It should now be possible to run the `fillUniverse` function and finally have life on your grid!
You can also play around with different `WIDTH`, `HEIGHT`, and `FPS` values and use different cell colors.
![Game of Life result][34]
(Mohammed Saud, [CC BY-SA 4.0][21])
### Try the game
If you use large sizes, make sure to grow the memory accordingly.
Here's the [complete code][35].
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/4/game-life-simulation-webassembly
作者:[Mohammed Saud][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/saud
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/OSDC_women_computing_3.png?itok=qw2A18BM (Woman sitting in front of her computer)
[2]: https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life
[3]: https://en.wikipedia.org/wiki/Cellular_automaton
[4]: https://en.wikipedia.org/wiki/Assembly_language
[5]: https://github.com/appcypher/awesome-wasm-langs
[6]: https://en.wikipedia.org/wiki/C_dynamic_memory_allocation
[7]: https://en.wikipedia.org/wiki/Closure_(computer_programming)
[8]: https://www.assemblyscript.org
[9]: https://www.typescriptlang.org/
[10]: https://nodejs.org/en/download/
[11]: https://webassembly.studio
[12]: http://december.com/html/4/element/html.html
[13]: http://december.com/html/4/element/head.html
[14]: http://december.com/html/4/element/meta.html
[15]: http://december.com/html/4/element/title.html
[16]: http://december.com/html/4/element/body.html
[17]: http://december.com/html/4/element/script.html
[18]: https://gist.github.com/willurd/5720255
[19]: https://www.npmjs.com/package/node-static
[20]: https://opensource.com/sites/default/files/uploads/console_log.png (console output)
[21]: https://creativecommons.org/licenses/by-sa/4.0/
[22]: http://december.com/html/4/element/canvas.html
[23]: http://december.com/html/4/element/style.html
[24]: https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API
[25]: https://developer.mozilla.org/en-US/docs/Web/API/ImageData
[26]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer
[27]: https://en.wikipedia.org/wiki/Endianness
[28]: https://opensource.com/sites/default/files/uploads/color_bits.png (Byte order for a pixel's color)
[29]: https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life#Rules
[30]: https://opensource.com/sites/default/files/uploads/count_neighbours.png (Coordinates of a cell's neighbors)
[31]: https://en.wikipedia.org/wiki/Torus
[32]: https://www.assemblyscript.org/peculiarities.html#annotations
[33]: https://www.assemblyscript.org/loader.html
[34]: https://opensource.com/sites/default/files/uploads/life.png (Game of Life result)
[35]: https://github.com/rottencandy/game-of-life-wasm

View File

@@ -1,306 +0,0 @@
[#]: subject: (Using Web Assembly Written in Rust on the Server-Side)
[#]: via: (https://www.linux.com/news/using-web-assembly-written-in-rust-on-the-server-side/)
[#]: author: (Dan Brown https://training.linuxfoundation.org/announcements/using-web-assembly-written-in-rust-on-the-server-side/)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
Using Web Assembly Written in Rust on the Server-Side
======
_By Bob Reselman_
_This article was originally published at [TheNewStac][1]k_
WebAssembly allows you to write code in a low-level programming language such as Rust, that gets compiled into a transportable binary. That binary can then be run on the client-side in the WebAssembly virtual machine that is [standard in todays web browsers][2]. Or, the binary can be used on the server-side, as a component consumed by another programming framework — such as Node.js or [Deno][3].
WebAssembly combines the efficiency inherent in low-level code programming with the ease of component transportability typically found in Linux containers. The result is a development paradigm specifically geared toward doing computationally intensive work at scale — for example, artificial intelligence and complex machine learning tasks.
As Solomon Hykes, the creator of Docker, [tweeted][4] on March 27, 2019: “If WASM+WASI existed in 2008, we wouldnt have needed to have created Docker. Thats how important it is. WebAssembly on the server is the future of computing.”
WebAssembly is a compelling approach to software development. However, in order to get a true appreciation for the technology, you need to see it in action.
In this article, I am going to show you how to program a WebAssembly binary in Rust and use it in a TypeScript-powered web server running under Deno. Ill show you how to install Rust and prep the runtime environment. Well compile the source code into a Rust binary. Then, once the binary is created, Ill demonstrate how to run it on the server-side under [Deno][3]. Deno is a TypeScript-based programming framework that was started by Ryan Dahl, the creator of Node.js.
### Understanding the Demonstration Project
The demonstration project that accompanies this article is called Wise Sayings. The project stores a collection of “wise sayings” in a text file named wisesayings.txt. Each line in the text file is a wise saying, for example, “_A friend in need is a friend indeed._”
The Rust code publishes a single function, get_wise_saying(). That function gets a random line from the text file, wisesayings.txt, and returns the random line to the caller. (See Figure 1, below)
<https://cdn.thenewstack.io/media/2021/03/50e3e12f-image1.png>
Figure 1: The demonstration project compiles data in a text file directly into the WebAssembly binary
Both the code and text file are compiled into a single WebAssembly binary file, named wisesayings.wasm. Then another layer of processing is performed to make the WebAssembly binary consumable by the Deno web server code. The Deno code calls the function get_wise_sayings() in the WebAssembly binary, to produce a random wise saying. (See Figure 2.)
<https://cdn.thenewstack.io/media/2021/03/ed3a0b83-image2.png>
Figure 2: WebAssembly binaries can be consumed by a server-side programming framework such as Deno.
_You get the source code for the Wise Sayings demonstration project used in this article [on GitHub][5]. All the steps described in this article are listed on the repositorys main [Readme][6] document._
### Prepping the Development Environment
The first thing we need to do to get the code up and running is to make sure that Rust is installed in the development environment. The following steps describe the process.
**Step 1: **Make sure Rust is installed on your machine by typing:
1 | rustc —version
---|---
Youll get output similar to the following:
1 | rustc 1.50.0 (cb75ad5db 20210210)
---|---
If the call to rustc version fails, you dont have Rust installed. Follow the instructions below and** make sure you do all the tasks presented by the given installation method**.
To install Rust, go here and install on Linux/MAC: …
1 | curl —proto =https —tlsv1.2 sSf <https://sh.rustup.rs>
---|---
… or here to install it on Windows:
Download and run rustup-init.exe which you can find at this URL: <https://static.rust-lang.org/rustup/dist/i686-pc-windows-gnu/rustup-init.exe>.
**Step 2:** Modify your systems PATH
1 | export PATH=“$HOME/.cargo/bin:$PATH”
---|---
**Step 3: **If youre working in a Linux environment do the following steps to install the required additional Linux components.
1 2 3 4 5 | sudo aptget update y sudo aptget install y libssldev apt install pkgconfig
---|---
***Developers Note: *_The optimal development environment in which to run this code is one that uses the Linux operating system._
**Step 4: **Get the CLI tool that youll use for generating the TypeScript/JavaScript adapter files. These adapter files (a.k.a. shims) do the work of exposing the function get_wise_saying() in the WebAssembly binary to the Deno web server that will be hosting the binary. Execute the following command at the command line to install the tool, [wasm-bindgen-cli][7].
1 | cargo install wasmbindgencli
---|---
The development environment now has Rust installed, along with the necessary ancillary libraries. Now we need to get the Wise Saying source code.
### Working with the Project Files
The Wise Saying source code is hosted in a GitHub repository. Take the following steps to clone the source code from GitHub onto the local development environment.
**Step 1: **Execute the following command to clone the Wise Sayings source code from GitHub
1 | git clone <https://github.com/reselbob/wisesayingswasm.git>
---|---
**Step 2: **Go to the working directory
1 | cd wisesayingswasm/
---|---
Listing 1, below lists the files that make up the source code cloned from the GitHub repository.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | . ├── Cargo.toml ├── cheatsheet.txt ├── LICENSE ├── lldbconfig ├── packagelock.json ├── README.md ├── server │   ├── main.ts │   └── packagelock.json └── src     ├── fortunes.txt     ├── lib.rs     └── main.rs
---|---
_Listing 1: The files for the source code for the Wise Sayings demonstration project hosted in the GitHub repository_
Lets take a moment to describe the source code files listed above in Listing 1. The particular files of interest with regard to creating the WebAssembly binary are the files in the directory named, src at Line 11 and the file, Cargo.toml at Line 2.
Lets discuss Cargo.toml first. The content of Cargo.toml is shown in Listing 2, below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | [package] name = “wise-sayings-wasm” version = “0.1.0” authors = [“Bob Reselman &lt;bob@CogArtTech.com&gt;”] edition = “2018” [dependencies] rand = “0.8.3” getrandom = { version = “0.2”, features = [“js”] } wasmbindgen = “0.2.70” [lib] name = “wisesayings” cratetype =[“cdylib”, “lib”]
---|---
_Listing 2: The content of Cargo.toml for the demonstration project Wise Sayings_
Cargo.toml is the [manifest file][8] that describes various aspects of the Rust project under development. The Cargo.toml file for the Wise Saying project is organized into three sections: package, dependencies, and lib. The section names are defined in the Cargo manifest specification, which you read [here][8].
#### Understanding the Package Section of Cargo.toml
The package section indicates the name of the package (wise-sayings-wasm), the developer assigned version (0.1.0), the authors (Bob Reselman &lt;[bob@CogArtTech.com][9]&gt;) and the edition of Rust (2018) that is used to program the binary.
#### Understanding the Dependencies Section of Cargo.toml
The dependencies section lists the dependencies that the WebAssembly project needs to do its work. As you can see in Listing 2, above at Line 8, the Cargo.toml lists the rand library as a dependency. The rand library provides the capability to generate a random number which is used to get a random line of wise saying text from the file, wisesayings.txt.
The reference to getrandom at Line 9 in Listing 2 above indicates that the WebAssembly binarys [getrandom][10] is running under Javascript and that the [JavaScript interface should be used][11]. This condition is very particular to running a WebAssembly binary under JavaScript. The long and short of it is that if the line getrandom = { version = “0.2”, features = [“js”] } is not included in the Cargo.toml, the WebAssembly binary will not be able to create a random number.
The entry at Line 10 declares the [wasm-bindgen][12] library as a dependency. The wasm-bindgen library provides the capability for wasm modules to talk to JavaScript and JavaScript to talk to wasm modules.
#### Understanding the Lib Section of Cargo.toml
The entry [crate-type =[“cdylib”, “lib”]][13] at Line 14 in the lib section of the Cargo.toml file tells the Rust compiler to create a wasm binary without a start function. Typically when cdylib is indicated, the compiler will create a [dynamic library][14] with the extension .dll in Windows, .so in Linux, or .dylib in MacOS. In this case, because the deployment unit is a WebAssembly binary, the compiler will create a file with the extension .wasm. The name of the wasm file will be wisesayings.wasm, as indicated at Line 13 above in Listing 2.
The important thing to understand about Cargo.toml is that it provides both the design and runtime information needed to get your Rust code up and running. If the Cargo.toml file is not present, the Rust compiler doesnt know what to do and the build will fail.
### Understanding the Core Function, get_wise_saying()
The actual work of getting a random line that contains a Wise Saying from the text file wisesayings.txt is done by the function get_wise_saying(). The code for get_wise_sayings() is in the Rust library file, ./src/lib.rs. The Rust code is shown below in Listing 3.
1 2 3 4 5 6 7 8 9 10 11 12 13 | use rand::seq::IteratorRandom; use wasm_bindgen::prelude::*; #[wasm_bindgen] pub fn get_wise_saying() -&gt; String {     let str = include_str!(“fortunes.txt”);     let mut lines = str.lines();     let line = lines         .choose(&amp;mut rand::thread_rng())         .expect(“File had no lines”);     return line.to_string(); }
---|---
_Listing 3: The function file, lib.rs contains the function, get_wise_saying()._
The important things to know about the source is that its tagged at Line 4 with the attribute #[wasm_bindgen], which lets the Rust compiler know that the source code is targeted as a WebAssembly binary. The code publishes one function, get_wise_saying(), at Line 5. The way the wise sayings text file is loaded into memory is to use the [Rust macro][15], [include_str!][16]. This macro does the work of getting the file from disk and loading the data into memory. The macro loads the file as a string and the function str.lines() separates the lines within the string into an array. (Line 7.)
The rand::thread_rng() call at Line 10 returns a number that is used as an index by the .choose() function at Line 10. The result of it all is an array of characters (a string) that reflects the wise saying returned by the function.
### Creating the WebAssembly Binary
Lets move on compiling the code into a WebAssembly Binary.
**Step 1: **Compile the source code into a WebAssembly is shown below.
1 | cargo build —lib —target wasm32unknownunknown
---|---
WHERE
**cargo build** is the command and subcommand to invoke the Rust compiler using the settings in the Cargo.toml file.
**lib** is the option indicating that youre going to build a library against the source code in the ./lib directory.
**targetwasm32-unknown-unknown** indicates that Rust will use the wasm-unknown-unknown compiler and will store the build artifacts as well as the WebAssembly binary into directories within the target directory, **wasm32-unknown-unknown.**
#### **Understanding the Rust Target Triple Naming Convention**
Rust has a naming convention for targets. The term used for the convention is a _target triple_. A target triple uses the following format: ARCH-VENDOR-SYS-ABI.
**WHERE**
**ARCH** describes the intended target architecture, for example wasm32 for WebAssembly, or i686 for current-generation Intel chips.
**VENDOR** describes the vendor publishing the target; for example, Apple or Nvidia.
**SYS** describes the operating system; for example, Windows or Linux.
**ABI** describes how the process starts up, for eabi is used for bare metal, while gnu is used for glibc.
Thus, the name i686-unknown-linux-gnu means that the Rust binary is targeted to an i686 architecture, the vendor is defined as unknown, the targeted operating system is Linux, and ABI is gnu.
In the case of wasm32-unknown-unknown, the target is WebAssembly, the operating system is unknown and the ABI is unknown. The informal inference of the name is “its a WebAssembly binary.”
There are a standard set of built-in targets defined by Rust that can be found [here][17].
If you find the naming convention to be confusing because there are optional fields and sometimes there are four sections to the name, while other times there will be three sections, you are not alone.
### Deploying the Binary Server-Side Using Deno
After we build the base WeAssembly binary, we need to create the adapter (a.k.a shim) files and a special version of the WebAssembly binary — all of which can be run from within JavaScript. Well create these artifacts using the [wasm-bindgen][18] tool.
**Step 1: **We create these new artifacts using the command shown below.
1 | wasmbindgen —target deno ./target/wasm32unknownunknown/debug/wisesayings.wasm —outdir ./server
---|---
WHERE
**wasm-bindgen** is the command for creating the adapter files and the special WebAssembly binary.
**target deno ./target/wasm32-unknown-unknown/debug/wisesayings.wasm** is the option that indicates the adapter files will be targeted for Deno. Also, the option denotes the location of the original WebAssembly wasm binary that is the basis for the artifact generation process.
**out-dir ./server** is the option that declares the location where the created adapter files will be stored on disk; in this case, **./server**.
The result of running wasm-bindgen is the server directory shown in Listing 4 below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | . ├── Cargo.toml ├── cheatsheet.txt ├── LICENSE ├── lldbconfig ├── packagelock.json ├── README.md ├── server │   ├── main.ts │   ├── packagelock.json │   ├── wisesayings_bg.wasm │   ├── wisesayings_bg.wasm.d.ts │   ├── wisesayings.d.ts │   └── wisesayings.js └── src     ├── fortunes.txt     ├── lib.rs     └── main.rs
---|---
_Listing 4: The server directory contains the results of running wasm-bindgen_
Notice that the contents of the server directory, shown above in Listing 4, now has some added JavaScript (js) and TypeScript (ts) files. Also, the server directory has the special version of the WebAssembly binary, named wisesayings_bg.wasm. This version of the WebAssembly binary is a stripped-down version of the wasm file originally created by the initial compilation, done when invoking cargo build earlier. You can think of this new wasm file as a JavaScript-friendly version of the original WebAssembly binary. The suffix, _bg, is an abbreviation for bindgen.
### Running the Deno Server
Once all the artifacts for running WebAssembly have been generated into the server directory, were ready to invoke the Deno web server. Listing 5 below shows content of main.ts, which is the source code for the Deno web server.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | import { serve } from “https://deno.land/std@0.86.0/http/server.ts”; import { get_wise_saying } from “./wisesayings.js”; const env = Deno.env.toObject(); let port = 4040; if(env.WISESAYING_PORT){   port = Number(env.WISESAYING_PORT); }; const server = serve({ hostname: “0.0.0.0”, port}); console.log(`HTTP webserver running at ${new Date()}.  Access it at:  http://localhost:${port}/`); for await (const request of server) {     const saying = get_wise_saying();     request.respond({ status: 200, body: saying });   }
---|---
_Listing 5: main.ts is the Deno webserver code that uses the WebAssembly binary_
Youll notice that the WebAssembly wasm binary is not imported directly. This is because the work of representing the WebAssembly binary is done by the JavaScript and TypeScript adapter (a.k.a shim) files generated earlier. The WebAssembly/Rust function, get_wise_sayings(), is exposed in the auto-generated JavaScript file, wisesayings.js.
The function get_wise_saying is imported into the webserver code at Line 2 above. The function is used at Line 16 to get a wise saying that will be returned as an HTTP response by the webserver.
To get the Deno web server up and running, execute the following command in a terminal window.
**Step 1:**
1 | deno run —allowread —allownet —allowenv ./main.ts
---|---
WHERE
deno run is the command set to invoke the webserver.
allow-read is the option that allows the Deno webserver code to have permission to read files from disk.
allow-net is the option that allows the Deno webserver code to have access to the network.
allow-env is the option that allows the Deno webserver code read environment variables.
./main.ts is the TypeScript file that Deno is to run. In this case, its the webserver code.
When the webserver is up and running, youll get output similar to the following:
HTTP webserver running at Thu Mar 11 2021 17:57:32 GMT+0000 (Coordinated Universal Time). Access it at: <http://localhost:4040/>
**Step 2:**
Run the following command in a terminal on your computer to exercise the Deno/WebAssembly code
1 | curl localhost:4040
---|---
Youll get a wise saying, for example:
_True beauty lies within._
**Congratulations!** Youve created and run a server-side WebAssembly binary.
### Putting It All Together
In this article, Ive shown you everything you need to know to create and use a WebAssembly binary in a Deno web server. Yet for as detailed as the information presented in this article is, there is still a lot more to learn about whats under the covers. Remember, Rust is a low-level programming language. Its meant to go right up against the processor and memory directly. Thats where its power really is. The real benefit of WebAssembly is using the technology to do computationally intensive work from within a browser. Applications that are well suited to WebAssembly are visually intensive games and activities that require complex machine learning capabilities — for example, real-time voice recognition and language translation. WebAssembly allows you to do computation on the client-side that previously was only possible on the server-side. As Solomon Hykes said, WebAssembly is the future of computing. He might very well be right.
The important thing to understand is that WebAssembly provides enormous opportunities for those wanting to explore cutting-edge approaches to modern distributed computing. Hopefully, the information presented in this piece will motivate you to explore those opportunities.
The post [Using Web Assembly Written in Rust on the Server-Side][19] appeared first on [Linux Foundation Training][20].
--------------------------------------------------------------------------------
via: https://www.linux.com/news/using-web-assembly-written-in-rust-on-the-server-side/
作者:[Dan Brown][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://training.linuxfoundation.org/announcements/using-web-assembly-written-in-rust-on-the-server-side/
[b]: https://github.com/lujun9972
[1]: https://thenewstack.io/using-web-assembly-written-in-rust-on-the-server-side/
[2]: https://www.infoq.com/news/2017/12/webassembly-browser-support/
[3]: https://deno.land/
[4]: https://twitter.com/solomonstre/status/1111004913222324225?s=20
[5]: https://github.com/reselbob/wisesayingswasm
[6]: https://github.com/reselbob/wisesayingswasm/blob/main/README.md
[7]: https://rustwasm.github.io/docs/wasm-bindgen/reference/cli.html
[8]: https://doc.rust-lang.org/cargo/reference/manifest.html
[9]: mailto:bob@CogArtTech.com
[10]: https://docs.rs/getrandom/0.2.2/getrandom/
[11]: https://docs.rs/getrandom/0.2.2/getrandom/#webassembly-support
[12]: https://rustwasm.github.io/docs/wasm-bindgen/
[13]: https://rustwasm.github.io/docs/wasm-pack/tutorials/npm-browser-packages/template-deep-dive/cargo-toml.html#1-crate-type
[14]: https://en.wikipedia.org/wiki/Library_(computing)#Shared_libraries
[15]: https://doc.rust-lang.org/book/ch19-06-macros.html
[16]: https://doc.rust-lang.org/std/macro.include_str.html
[17]: https://docs.rust-embedded.org/embedonomicon/compiler-support.html#built-in-target
[18]: https://rustwasm.github.io/wasm-bindgen/
[19]: https://training.linuxfoundation.org/announcements/using-web-assembly-written-in-rust-on-the-server-side/
[20]: https://training.linuxfoundation.org/

View File

@@ -1,140 +0,0 @@
[#]: subject: (Resolve systemd-resolved name-service failures with Ansible)
[#]: via: (https://opensource.com/article/21/4/systemd-resolved)
[#]: author: (David Both https://opensource.com/users/dboth)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
Resolve systemd-resolved name-service failures with Ansible
======
Name resolution and the ever-changing networking landscape.
![People work on a computer server with devices][1]
Most people tend to take name services for granted. They are necessary to convert human-readable names, such as `www.example.com`, into IP addresses, like `93.184.216.34`. It is easier for humans to recognize and remember names than IP addresses, and name services allow us to use names, and they also convert them to IP addresses for us.
The [Domain Name System][2] (DNS) is the global distributed database that maintains the data required to perform these lookups and reverse lookups, in which the IP address is known and the domain name is needed.
I [installed Fedora 33][3] the first day it became available in October 2020. One of the major changes was a migration from the ancient Name Service Switch (NSS) resolver to [systemd-resolved][4]. Unfortunately, after everything was up and running, I couldn't connect to or even ping any of the hosts on my network by name, although using IP addresses did work.
### The problem
I run my own name server using BIND on my network server, and all has been good for over 20 years. I've configured my DHCP server to provide the IP address of my name server to every workstation connected to my network, and that (along with a couple of backup name servers) is stored in `/etc/resolv.conf`.
[Michael Catanzaro][5] describes how systemd-resolved is supposed to work, but the introduction of systemd-resolved caused various strange resolution problems on my network hosts. The symptoms varied depending upon the host's purpose. The trouble mostly presented as an inability to find IP addresses for hosts inside the network on most systems. On other systems, it failed to resolve any names at all. For example, even though nslookup sometimes returned the correct IP addresses for hosts inside and outside networks, ping would not contact the designated host, nor could I SSH to that same host. Most of the time, neither the lookup, the ping, nor SSH would work unless I used the IP address in the command.
The new resolver allegedly has four operational modes, described in this [Fedora Magazine article][6]. None of the options seems to work correctly when the network has its own name server designed to perform lookups for internal and external hosts.
In theory, systemd-resolved is supposed to fix some corner issues around the NSS resolver failing to use the correct name server when a host is connected to a VPN, which has become a common problem with so many more people working from home.
The new resolver is supposed to use the fact that `/etc/resolv.conf` is now a symlink to determine how it is supposed to work based on which resolve file it is linked to. systemd-resolved's man page includes details about this behavior. The man page says that setting `/etc/resolv.conf` as a symlink to `/run/systemd/resolve/resolv.conf` should cause the new resolver to work the same way the old one does, but that didn't work for me.
### My fix
I have seen many options on the internet for resolving this problem, but the only thing that works reliably for me is to stop and disable the new resolver. First, I deleted the existing link for `resolv.conf`, copied my preferred `resolv.conf` file to `/run/NetworkManager/resolv.conf`, and added a new link to that file in `/etc`:
```
# rm -f /etc/resolv.conf
# ln -s /run/NetworkManager/resolv.conf /etc/resolv.conf
```
These commands stop and disable the systemd-resolved service:
```
# systemctl stop systemd-resolved.service ; systemctl disable systemd-resolved.service
Removed /etc/systemd/system/multi-user.target.wants/systemd-resolved.service.
Removed /etc/systemd/system/dbus-org.freedesktop.resolve1.service.
```
There's no reboot required. The old resolver takes over, and name services work as expected.
### Make it easy with Ansible
I set up this Ansible playbook to make the necessary changes if I install a new host or an update that reverts the resolver to systemd-resolved, or if an upgrade to the next release of Fedora reverts the resolver. The `resolv.conf` file you want for your network should be located in `/root/ansible/resolver/files/`:
```
################################################################################
#                              fixResolver.yml                                 #
#------------------------------------------------------------------------------#
#                                                                              #
# This playbook configures the old nss resolver on systems that have the new   #
# systemd-resolved service installed. It copies the resolv.conf file for my    #
# network to /run/NetworkManager/resolv.conf and places a link to that file    #
# as /etc/resolv.conf. It then stops and disables systemd-resolved which       #
# activates the old nss resolver.                                              #
#                                                                              #
#------------------------------------------------------------------------------#
#                                                                              #
# Change History                                                               #
# Date        Name         Version   Description                               #
# 2020/11/07  David Both   00.00     Started new code                          #
# 2021/03/26  David Both   00.50     Tested OK on multiple hosts.              #
#                                                                              #
################################################################################
\---
\- name: Revert to old NSS resolver and disable the systemd-resolved service
  hosts: all_by_IP
################################################################################
  tasks:
    - name: Copy resolv.conf for my network
      copy:
        src: /root/ansible/resolver/files/resolv.conf
        dest: /run/NetworkManager/resolv.conf
        mode: 0644
        owner: root
        group: root
    - name: Delete existing /etc/resolv.conf file or link
      file:
        path: /etc/resolv.conf
        state: absent
    - name: Create link from /etc/resolv.conf to /run/NetworkManager/resolv.conf
      file:
        src: /run/NetworkManager/resolv.conf
        dest: /etc/resolv.conf
        state: link
    - name: Stop and disable systemd-resolved
      systemd:
        name: systemd-resolved
        state: stopped
        enabled: no
```
Whichever Ansible inventory you use must have a group that uses IP addresses instead of hostnames. This command runs the playbook and specifies the name of the inventory file I use for hosts by IP address:
```
`# ansible-playbook -i /etc/ansible/hosts_by_IP fixResolver.yml`
```
### Final thoughts
Sometimes the best answer to a tech problem is to fall back to what you know. When systemd-resolved is more robust, I'll likely give it another try, but for now I'm glad that open source infrastructure allows me to quickly identify and resolve network problems. Using Ansible to automate the process is a much appreciated bonus. The important lesson here is to do your research when troubleshooting, and to never be afraid to void your warranty.
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/4/systemd-resolved
作者:[David Both][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/dboth
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/rh_003499_01_linux11x_cc.png?itok=XMDOouJR (People work on a computer server with devices)
[2]: https://opensource.com/article/17/4/introduction-domain-name-system-dns
[3]: https://opensource.com/article/20/11/new-gnome
[4]: https://www.freedesktop.org/software/systemd/man/systemd-resolved.service.html
[5]: https://blogs.gnome.org/mcatanzaro/2020/12/17/understanding-systemd-resolved-split-dns-and-vpn-configuration/
[6]: https://fedoramagazine.org/systemd-resolved-introduction-to-split-dns/

View File

@@ -1,228 +0,0 @@
[#]: subject: (Notes on building debugging puzzles)
[#]: via: (https://jvns.ca/blog/2021/04/16/notes-on-debugging-puzzles/)
[#]: author: (Julia Evans https://jvns.ca/)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
Notes on building debugging puzzles
======
Hello! This week I started building some choose-your-own-adventure-style puzzles about debugging networking problems. Im pretty excited about it and Im trying to organize my thoughts so heres a blog post!
The two Ive made so far are:
* [The Case of the Connection Timeout][1]
* [The Case of the Slow Website][2]
Ill talk about how I came to this idea, design decisions I made, how it works, what I think is hard about making these puzzles, and some feedback Ive gotten so far.
### why this choose-your-own-adventure format?
Ive been thinking a lot about DNS recently, and how to help people troubleshoot their DNS issues. So on Tuesday I was sitting in a park with a couple of friends chatting about this.
We started out by talking about the idea of flowcharts (“heres a flowchart that will help you debug any DNS problem”). Ive dont think Ive ever seen a flowchart that I found helpful in solving a problem, so I found it really hard to imagine creating one there are so many possibilities! Its hard to be exhaustive! It would be disappointing if the flowchart failed and didnt give you your answer!
But then someone mentioned choose-your-own-adventure games, and I thought about something I **could** relate to debugging a problem together with someone who knows things that I dont!
So I thought what if I made a choose-your-own-adventure game where youre given the symptoms of a specific networking bug, and you have to figure out how to diagnose it?
I got really excited about this and immediately went home and started putting something together in Twine.
Here are some design decisions Ive made so far. Some of them might change.
### design decision: the mystery has 1 specific bug
Each mystery has one very specific bug, ideally a bug that Ive actually run into in the past. Your mission is to figure out the cause of the bug and fix it.
### design decision: show people the actual output of the tools theyre using
All of the bugs Im starting with are networking issues, and the way you solve them is to use various tools (like dig, curl, tcpdump, ping, etc) to get more information.
Originally I thought of writing the game like this:
1. You choose “Use curl”
2. It says “You run `<command>`. You see that the output tells you `<interpretation>`
But I realized that immediately interpreting the output of a command for someone is extremely unrealistic one of the biggest problems with using some of these command line networking tools is that their output is hard to interpret!
So instead, the puzzle:
1. Asks what tool you want to use
2. Tells you what command they ran, and shows you the output of the command
3. Asks you to interpret the output (you type it in in a freeform text box)
4. Tells you the “correct” interpretation of the output and shows you how you could have figured it out (by highlighting the relevant parts of the output)
This really lines up with how Ive learned about these tools in real life I dont learn about how to read all of the output all at once, I learn it in bits and pieces by debugging real problems.
### design decision: make the output realistic
This is sort of obvious, but in order to give someone output to help them diagnose a bug, the output needs to be a realistic representation of what would actually happen.
Ive been doing this by reproducing the bug in a virtual machine (or on my laptop), and then running the commands in the same way I would to fix the bug in real life and paste their output.
Reproducing the bug isnt always easy, but once Ive reproduced it it makes building the puzzle much more straightforward than trying to imagine what tcpdump would theoretically output in a given situation.
### design decision: let people collect “knowledge” throughout the mystery
When I debug, I think about it as slowly collecting new pieces of information as I go. So in this mystery, every time you figure out a new piece of information, you get a little box that looks like this:
![][3]
And in the sidebar, you have a sort of “inventory” that lists all of the knowledge youve collected so far. It looks like this:
![][4]
### design decision: you always figure out the bug
My friend Sumana pointed out an interesting difference between this and normal choose-your-own-adventure games: in the choose-your-own-adventure games I grew up reading, you lose a lot! You make the wrong choice, and you fall into a pit and die.
But thats not how debugging works in my experience. When debugging, if you make a “wrong” choice (for example by making a guess about the bug that isnt correct), theres no cost except your time! So you can always go back, keep trying, and eventually figure out whats going on.
I think that “you always win” is sort of realistic in the sense that with any bug you can always figure out what the bug is, given:
1. enough time
2. enough understanding of how the systems youre debugging work
3. tools that can give you information about whats happening
Im still not sure if I want all bugs to result in “you fix the bug!” sometimes bugs are impossible to fix if theyre caused by a system thats outside of your control! One really interesting idea Sumana had was to have the resolution sometimes be “you submit a really clear and convincing bug report and someone else fixes it”.
### design decision: include red herrings sometimes
In debugging in real life, there are a lot of red herrings! Sometimes you see something that looks weird, and you spend three hours looking into it, and then you realize that wasnt it at all.
One of the mysteries right now has a red herring, and the way I came up with it was that I ran a command and I thought “wait, the output of that is pretty confusing, its not clear how to interpret that”. So I just included the confusing output in the mystery and said “hey, what do you think it means?”.
One thing I like about including red herrings is that it lets me show how you can prove what the cause of the bug **isnt** which is even harder than proving what the cause of the bug is.
### design decision: use free form text boxes
Heres an example of what it looks like to be asked to interpret some output. Youre asked a question and you fill in the answer in a text box.
![][5]
I think I like using free form text boxes instead of multiple choice because it feels a little more realistic to me in real life, when you see some output like this, you dont get a list of choices!
### design decision: dont do anything with what you enter in the text box
No matter what you enter in the text box (or if you say “I dont know”), exactly the same thing happens. Itll send you to a page that tells you the answer and explains the reasoning. So you have to think about what you think the answer might be, but if you get it “wrong”, its no big deal.
The reason Im doing this is basically “its very easy to implement”, but I think theres maybe also something nice about it for the person using it if you dont know, its totally okay! You can learn something new and keep moving! You dont get penalized for your “wrong” answers in any way.
### design decision: the epilogue
At the end of the game, theres a very short epilogue where it talks about how likely you are to run into this bug in real life / how realistic this is. I think I need to expand on this to answer other questions people might have had while going through it, but I think its going to be a nice place to wrap up loose ends.
### how long each one takes to play: 5 minutes
People seem to report so far that each mystery takes about 5 minutes to play, which feels reasonable to me. I think Im most likely to extend this by making lots of different 5-minute mysteries rather than making one really long mystery, but well see.
### whats hard: reproducing the bug
Figuring out how to reproduce a given bug is actually not that easy I think I want to include some pretty weird bugs, and setting up a computer where that bug is happening in a realistic way isnt actually that easy. I think this just takes some work and creativity though.
### whats hard: giving realistic options
The most common critique I got was of the form “In this situation I would have done X but you didnt include X as an option”. Some examples of X: “ping the problem host”, “ssh to the problem host and run tcpdump there”, “look at the log file”, “use netstat”, etc.
I think its possible to make a lot of progress on this with playtesting if I playtest a mystery with a bunch of people and ask them to tell me when there was an option they wish they had, I can add that option pretty easily!
Because I can actually reproduce the bug, providing an option like “run netstat” is pretty straightforward all I have to do is go to the VM where Ive reproduced the bug, run `netstat`, and put the output into the game.
A couple of people also said that the game felt too “linear” or didnt branch enough. Im curious about whether that will naturally come out of having more realistic options.
### how it works: its a Twine game!
I felt like Twine was the obvious choice for this even though Id never used it before Id heard so many good things about it over the years.
You can see all of the source code for The Case of the Connection Timeout in [connection-timeout.twee][6] and [common.twee][7], which has some shared code between all the games.
A few notes about using Twine:
* Im using SugarCube, the [sugarcube docs are very good][8]
* Im using [tweego][9] to translate the `.twee` files in to a HTML page. I started out using the visual Twine editor to do my editing but switched to `tweego` pretty quickly because I wanted to use version control and have a more text-based workflow.
* The final output is one big HTML file that includes all the images and CSS and Javascript inline. The final HTML files are about 800K which seems reasonable to me.
* I base64-encode all the images in the game and include them inline in the file
* The [Twine wiki][10] and forums have a lot of great information and between the Twine wiki, the forums, and the Sugarcube docs I could pretty easily find answers to all my questions.
I used pretty much the exact Twine workflow from Em Lazerwalkers great post [A Modern Developers Workflow For Twine][11].
I wont explain how Twine works because it has great documentation and it would make this post way too long.
### some feedback so far
I posted this on Twitter and asked for feedback. Some common pieces of feedback I got:
things people liked:
* maybe 180 “I love this, this was so fun, I learned something new”
* A bunch of people specifically said that they liked learning how to interpret tcpdumps output format
* A few people specifically mentioned that they liked the “what you know” list and the mechanic of hunting for clues and how it breaks down the debugging process.
some suggestions for improvements:
* Like I mentioned before, lots of people said “I wanted to try X but it wasnt an option”
* One of the puzzles had a resolution to the bug that some people found unsatisfying (they felt it was more of a workaround than a fix, which I agreed with). I updated it to add a different resolution that was more satisfying.
* There were some technical issues (it could be more mobile-friendly, one of the images was hard to read, I needed to add a “Submit” button to one of the forms)
* Right now the way the text boxes work is that no matter what you type, the exact same thing happens. Some people found this a bit confusing, like “why did it act like I answered correctly if my answer was wrong”. This definitely needs some work.
### some goals of this project
Heres what I think the goals of this project are:
1. help people learn about **tools** (like tcpcdump, dig, and curl). How do you use each tool? What questions can they be used to answer? How do you interpret their output?
2. help people learn about **bugs**. There are some super common bugs that we run into over and over, and once you see a bug once its easier to recognize the same bug in the future.
3. help people get better at the **debugging process** (gathering data, asking questions)
### what experience is this trying to imitate?
Something I try to keep in mind with all my projects is what real-life experience does this reproduce? For example, I kind of think of my zines as being the experience “your coworker explains something to you in a really clear way”.
I think the experience here might be “youre debugging a problem together with your coworker and theyre really knowledgeable about the tools youre using”.
### thats all!
Im pretty excited about this project right now Im going to build at least a couple more of these and see how it goes! If things go well I might make this into my first non-zine thing for sale maybe itll be a collection of 12 small debugging mysteries! Well see.
--------------------------------------------------------------------------------
via: https://jvns.ca/blog/2021/04/16/notes-on-debugging-puzzles/
作者:[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://mysteries.wizardzines.com/connection-timeout.html
[2]: https://mysteries.wizardzines.com/slow-website.html
[3]: https://jvns.ca/images/newinfo.png
[4]: https://jvns.ca/images/sidebar-mystery.png
[5]: https://jvns.ca/images/textboxes.png
[6]: https://github.com/jvns/twine-stories/blob/2914c4326e3ff760a0187b2cfb15161928d6335b/connection-timeout.twee
[7]: https://github.com/jvns/twine-stories/blob/2914c4326e3ff760a0187b2cfb15161928d6335b/common.twee
[8]: https://www.motoslave.net/sugarcube/2/docs/
[9]: https://www.motoslave.net/tweego/
[10]: https://twinery.org/wiki/
[11]: https://dev.to/lazerwalker/a-modern-developer-s-workflow-for-twine-4imp

View File

@@ -1,436 +0,0 @@
[#]: subject: (Use the DNF local plugin to speed up your home lab)
[#]: via: (https://fedoramagazine.org/use-the-dnf-local-plugin-to-speed-up-your-home-lab/)
[#]: author: (Brad Smith https://fedoramagazine.org/author/buckaroogeek/)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
Use the DNF local plugin to speed up your home lab
======
![][1]
Photo by [Sven Hornburg][2] on [Unsplash][3]
### Introduction
If you are a Fedora Linux enthusiast or a developer working with multiple instances of Fedora Linux then you might benefit from the [DNF local][4] plugin. An example of someone who would benefit from the DNF local plugin would be an enthusiast who is running a cluster of Raspberry Pis. Another example would be someone running several virtual machines managed by Vagrant. The DNF local plugin reduces the time required for DNF transactions. It accomplishes this by transparently creating and managing a local RPM repository. Because accessing files on a local file system is significantly faster than downloading them repeatedly, multiple Fedora Linux machines will see a significant performance improvement when running _dnf_ with the DNF local plugin enabled.
I recently started using this plugin after reading a tip from Glenn Johnson (aka glennzo) in [a 2018 fedoraforum.org post][5]. While working on a Raspberry Pi based Kubernetes cluster running Fedora Linux and also on several container-based services, I winced with every DNF update on each Pi or each container that downloaded a duplicate set of rpms across my expensive internet connection. In order to improve this situation, I searched for a solution that would cache rpms for local reuse. I wanted something that would not require any changes to repository configuration files on every machine. I also wanted it to continue to use the network of Fedora Linux mirrors. I didnt want to use a single mirror for all updates.
### Prior art
An internet search yields two common solutions that eliminate or reduce repeat downloads of the same RPM set create a private Fedora Linux mirror or set up a caching proxy.
Fedora provides guidance on setting up a [private mirror][6]. A mirror requires a lot of bandwidth and disk space and significant work to maintain. A full private mirror would be too expensive and it would be overkill for my purposes.
The most common solution I found online was to implement a caching proxy using Squid. I had two concerns with this type of solution. First, I would need to edit repository definitions stored in _/etc/yum.repo.d_ on each virtual and physical machine or container to use the same mirror. Second, I would need to use _http_ and not _https_ connections which would introduce a security risk.
After reading Glenns 2018 post on the DNF local plugin, I searched for additional information but could not find much of anything besides the sparse documentation for the plugin on the DNF documentation web site. This article is intended to raise awareness of this plugin.
### About the DNF local plugin
The [online documentation][4] provides a succinct description of the plugin: “Automatically copy all downloaded packages to a repository on the local filesystem and generating repo metadata”. The magic happens when there are two or more Fedora Linux machines configured to use the plugin and to share the same local repository. These machines can be virtual machines or containers running on a host and all sharing the host filesystem, or separate physical hardware on a local area network sharing the file system using a network-based file system sharing technology. The plugin, once configured, handles everything else transparently. Continue to use _dnf_ as before. _dnf_ will check the plugin repository for rpms, then proceed to download from a mirror if not found. The plugin will then cache all rpms in the local repository regardless of their upstream source an official Fedora Linux repository or a third-party RPM repository and make them available for the next run of _dnf_.
### Install and configure the DNF local plugin
Install the plugin using _dnf_. The _createrepo_c_ packages will be installed as a dependency. The latter is used, if needed, to create the local repository.
```
sudo dnf install python3-dnf-plugin-local
```
The plugin configuration file is stored at /_etc/dnf/plugins/local.conf_. An example copy of the file is provided below. The only change required is to set the _repodir_ option. The _repodir_ option defines where on the local filesystem the plugin will keep the RPM repository.
```
[main]
enabled = true
# Path to the local repository.
# repodir = /var/lib/dnf/plugins/local
# Createrepo options. See man createrepo_c
[createrepo]
# This option lets you disable createrepo command. This could be useful
# for large repositories where metadata is priodically generated by cron
# for example. This also has the side effect of only copying the packages
# to the local repo directory.
enabled = true
# If you want to speedup createrepo with the --cachedir option. Eg.
# cachedir = /tmp/createrepo-local-plugin-cachedir
# quiet = true
# verbose = false
```
Change _repodir_ to the filesystem directory where you want the RPM repository stored. For example, change _repodir_ to _/srv/repodir_ as shown below.
```
...
# Path to the local repository.
# repodir = /var/lib/dnf/plugins/local
repodir = /srv/repodir
...
```
Finally, create the directory if it does not already exist. If this directory does not exist, _dnf_ will display some errors when it first attempts to access the directory. The plugin will create the directory, if necessary, despite the initial errors.
```
sudo mkdir -p /srv/repodir
```
Repeat this process on any virtual machine or container that you want to share the local repository. See the use cases below for more information. An alternative configuration using NFS (network file system) is also provided below.
### How to use the DNF local plugin
After you have installed the plugin, you do not need to change how you use _dnf_. The plugin will cause a few additional steps to run transparently behind the scenes whenever _dnf_ is called. After _dnf_ determines which rpms to update or install, the plugin will try to retrieve them from the local repository before trying to download them from a mirror. After _dnf_ has successfully completed the requested updates, the plugin will copy any rpms downloaded from a mirror to the local repository and then update the local repositorys metadata. The downloaded rpms will then be available in the local repository for the next _dnf_ client.
There are two points to be aware of. First, benefits from the local repository only occur if multiple machines share the same architecture (for example, x86_64 or aarch64). Virtual machines and containers running on a host will usually share the same architecture as the host. But if there is only one aarch64 device and one x86_64 device there is little real benefit to a shared local repository unless one of the devices is constantly reset and updated which is common when developing with a virtual machine or container. Second, I have not explored how robust the local repository is to multiple _dnf_ clients updating the repository metadata concurrently. I therefore run _dnf_ from multiple machines serially rather than in parallel. This may not be a real concern but I want to be cautious.
The use cases outlined below assume that work is being done on Fedora Workstation. Other desktop environments can work as well but may take a little extra effort. I created a GitHub repository with examples to help with each use case. Click the _Code_ button at <https://github.com/buckaroogeek/dnf-local-plugin-examples> to clone the repository or to download a zip file.
#### Use case 1: networked physical machines
The simplest use case is two or more Fedora Linux computers on the same network. Install the DNF local plugin on each Fedora Linux machine and configure the plugin to use a repository on a network-aware file system. There are many network-aware file systems to choose from. Which file system you will use will probably be influenced by the existing devices on your network.
For example, I have a small Synology Network Attached Storage device (NAS) on my home network. The web admin interface for the Synology makes it very easy to set up a NFS server and export a file system share to other devices on the network. NFS is a shared file system that is well supported on Fedora Linux. I created a share on my NAS named _nfs-dnf_ and exported it to all the Fedora Linux machines on my network. For the sake of simplicity, I am omitting the details of the security settings. However, please keep in mind that security is always important even on your own local network. If you would like more information about NFS, the online Red Hat Enable Sysadmin magazine has an [informative post][7] that covers both client and server configurations on Red Hat Enterprise Linux. They translate well to Fedora Linux.
I configured the NFS client on each of my Fedora Linux machines using the steps shown below. In the below example, _quga.lan_ is the hostname of my NAS device.
Install the NFS client on each Fedora Linux machine.
```
$ sudo dnf install nfs-utils
```
Get the list of exports from the NFS server:
```
$ showmount -e quga.lan
Export list for quga.lan:
/volume1/nfs-dnf pi*.lan
```
Create a local directory to be used as a mount point on the Fedora Linux client:
```
$ sudo mkdir -p /srv/repodir
```
Mount the remote file system on the local directory. See _man mount_ for more information and options.
```
$ sudo mount -t nfs -o vers=4 quga.lan:/nfs-dnf /srv/repodir
```
The DNF local plugin will now work until as long as the client remains up. If you want the NFS export to be automatically mounted when the client is rebooted, then you must to edit /_etc/fstab_ as demonstrated below. I recommend making a backup of _/etc/fstab_ before editing it. You can substitute _vi_ with _nano_ or another editor of your choice if you prefer.
```
$ sudo vi /etc/fstab
```
Append the following line at the bottom of _/etc/fstab_, then save and exit.
```
quga.lan:/volume1/nfs-dnf /srv/repodir nfs defaults,timeo=900,retrans=5,_netdev 0 0
```
Finally, notify systemd that it should rescan _/etc/fstab_ by issuing the following command.
```
$ sudo systemctl daemon-reload
```
NFS works across the network and, like all network traffic, may be blocked by firewalls on the client machines. Use _firewall-cmd_ to allow NFS-related network traffic through each Fedora Linux machines firewall.
```
$ sudo firewall-cmd --permanent --zone=public --allow-service=nfs
```
As you can imagine, replicating these steps correctly on multiple Fedora Linux machines can be challenging and tedious. Ansible automation solves this problem.
In the _rpi-example_ directory of the github repository Ive included an example Ansible playbook (_configure.yaml_) that installs and configures both the DNF plugin and the NFS client on all Fedora Linux machines on my network. There is also a playbook (_update.yaml)_ that runs a DNF update across all devices. See this [recent post in Fedora Magazine][8] for more information about Ansible.
To use the provided Ansible examples, first update the inventory file (_inventory_) to include the list of Fedora Linux machines on your network that you want to managed. Next, install two Ansible roles in the roles subdirectory (or another suitable location).
```
$ ansible-galaxy install --roles-path ./roles -r requirements.yaml
```
Run the _configure.yaml_ playbook to install and configure the plugin and NFS client on all hosts defined in the inventory file. The role that installs and configures the NFS client does so via _/etc/fstab_ but also takes it a step further by creating an automount for the NFS share in systemd. The automount is configured to mount the share only when needed and then to automatically unmount. This saves network bandwidth and CPU cycles which can be important for low power devices like a Raspberry Pi. See the github repository for the role and for more information.
```
$ ansible-playbook -i inventory configure.yaml
```
Finally, Ansible can be configured to execute _dnf update_ on all the systems serially by using the _update.yaml_ playbook.
```
$ ansible-playbook -i inventory update.yaml
```
Ansible and other automation tools such as Puppet, Salt, or Chef can be big time savers when working with multiple virtual or physical machines that share many characteristics.
#### Use case 2: virtual machines running on the same host
Fedora Linux has excellent built-in support for virtual machines. The Fedora Project also provides [Fedora Cloud][9] base images for use as virtual machines. [Vagrant][10] is a tool for managing virtual machines. Fedora Magazine has [instructions][11] on how to set up and configure Vagrant. Add the following line in your _.bashrc_ (or other comparable shell configuration file) to inform Vagrant to use _libvirt_ automatically on your workstation instead of the default VirtualBox.
```
export VAGRANT_DEFAULT_PROVIDER=libvirt
```
In your project directory initialize Vagrant and the Fedora Cloud image (use 34-cloud-base for Fedora Linux 34 when available):
```
$ vagrant init fedora/33-cloud-base
```
This creates a Vagrant file in the project directory. Edit the Vagrant file to look like the example below. DNF will likely fail with the default memory settings for _libvirt_. So the example Vagrant file below provides additional memory to the virtual machine. The example below also shares the host _/srv/repodir_ with the virtual machine. The shared directory will have the same path in the virtual machine _/srv/repodir_. The Vagrant file can be downloaded from [github][12].
```
# -*- mode: ruby -*-
# vi: set ft=ruby :
# define repo directory; same name on host and vm
REPO_DIR = "/srv/repodir"
Vagrant.configure("2") do |config|
config.vm.box = "fedora/33-cloud-base"
config.vm.provider :libvirt do |v|
v.memory = 2048
# v.cpus = 2
end
# share the local repository with the vm at the same location
config.vm.synced_folder REPO_DIR, REPO_DIR
# ansible provisioner - commented out by default
# the ansible role is installed into a path defined by
# ansible.galaxy_roles-path below. The extra_vars are ansible
# variables passed to the playbook.
#
# config.vm.provision "ansible" do |ansible|
# ansible.verbose = "v"
# ansible.playbook = "ansible/playbook.yaml"
# ansible.extra_vars = {
# repo_dir: REPO_DIR,
# dnf_update: false
# }
# ansible.galaxy_role_file = "ansible/requirements.yaml"
# ansible.galaxy_roles_path = "ansible/roles"
# end
end
```
Once you have Vagrant managing a Fedora Linux virtual machine, you can install the plugin manually. SSH into the virtual machine:
```
$ vagrant ssh
```
When you are at a command prompt in the virtual machine, repeat the steps from the _Install and configure the DNF local plugin_ section above. The Vagrant configuration file should have already made _/srv/repodir_ from the host available in the virtual machine at the same path.
If you are working with several virtual machines or repeatedly re-initiating a new virtual machine then some simple automation becomes useful. As with the network example above, I use ansible to automate this process.
In the [vagrant-example directory][12] on github, you will see an _ansible_ subdirectory. Edit the Vagrant file and remove the comment marks under the _ansible provisioner_ section. Make sure the _ansible_ directory and its contents (_playbook.yaml_, _requirements.yaml_) are in the project directory.
After youve uncommented the lines, the _ansible provisioner_ section in the Vagrant file should look similar to the following:
```
....
# ansible provisioner
# the ansible role is installed into a path defined by
# ansible.galaxy_roles-path below. The extra_vars are ansible
# variables passed to the playbook.
#
config.vm.provision "ansible" do |ansible|
ansible.verbose = "v"
ansible.playbook = "ansible/playbook.yaml"
ansible.extra_vars = {
repo_dir: REPO_DIR,
dnf_update: false
}
ansible.galaxy_role_file = "ansible/requirements.yaml"
ansible.galaxy_roles_path = "ansible/roles"
end
....
```
Ansible must be installed (_sudo dnf install ansible_). Note that there are significant changes to how Ansible is packaged beginning with Fedora Linux 34 (use _sudo dnf install ansible-base ansible-collections*_).
If you run Vagrant now (or reprovision: _vagrant provision_), Ansible will automatically download an Ansible role that installs the DNF local plugin. It will then use the downloaded role in a playbook. You can _vagrant ssh_ into the virtual machine to verify that the plugin is installed and to verify that rpms are coming from the DNF local repository instead of a mirror.
#### Use case 3: container builds
Container images are a common way to distribute and run applications. If you are a developer or enthusiast using Fedora Linux containers as a foundation for applications or services, you will likely use _dnf_ to update the container during the development/build process. Application development is iterative and can result in repeated executions of _dnf_ pulling the same RPM set from Fedora Linux mirrors. If you cache these rpms locally then you can speed up the container build process by retrieving them from the local cache instead of re-downloading them over the network each time. One way to accomplish this is to create a custom Fedora Linux container image with the DNF local plugin installed and configured to use a local repository on the host workstation. Fedora Linux offers _podman_ and _buildah_ for managing the container build, run and test life cycle. See the Fedora Magazine post [_How to build Fedora container images_][13] for more about managing containers on Fedora Linux.
Note that the _fedora_minimal_ container uses _microdnf_ by default which does not support plugins. The _fedora_ container, however, uses _dnf_.
A script that uses _buildah_ and _podman_ to create a custom Fedora Linux image named _myFedora_ is provided below. The script creates a mount point for the local repository at _/srv/repodir_. The below script is also available in the [_container-example_][14] directory of the github repository. It is named _base-image-build.sh_.
```
#!/bin/bash
set -x
# bash script that creates a 'myfedora' image from fedora:latest.
# Adds dnf-local-plugin, points plugin to /srv/repodir for local
# repository and creates an external mount point for /srv/repodir
# that can be used with a -v switch in podman/docker
# custom image name
custom_name=myfedora
# scratch conf file name
tmp_name=local.conf
# location of plugin config file
configuration_name=/etc/dnf/plugins/local.conf
# location of repodir on container
container_repodir=/srv/repodir
# create scratch plugin conf file for container
# using repodir location as set in container_repodir
cat <<EOF > "$tmp_name"
[main]
enabled = true
repodir = $container_repodir
[createrepo]
enabled = true
# If you want to speedup createrepo with the --cachedir option. Eg.
# cachedir = /tmp/createrepo-local-plugin-cachedir
# quiet = true
# verbose = false
EOF
# pull registry.fedoraproject.org/fedora:latest
podman pull registry.fedoraproject.org/fedora:latest
#start the build
mkdev=$(buildah from fedora:latest)
# tag author
buildah config --author "$USER" "$mkdev"
# install dnf-local-plugin, clean
# do not run update as local repo is not operational
buildah run "$mkdev" -- dnf --nodocs -y install python3-dnf-plugin-local createrepo_c
buildah run "$mkdev" -- dnf -y clean all
# create the repo dir
buildah run "$mkdev" -- mkdir -p "$container_repodir"
# copy the scratch plugin conf file from host
buildah copy "$mkdev" "$tmp_name" "$configuration_name"
# mark container repodir as a mount point for host volume
buildah config --volume "$container_repodir" "$mkdev"
# create myfedora image
buildah commit "$mkdev" "localhost/$custom_name:latest"
# clean up working image
buildah rm "$mkdev"
# remove scratch file
rm $tmp_name
```
Given normal security controls for containers, you usually run this script with _sudo_ and when you use the _myFedora_ image in your development process.
```
$ sudo ./base_image_build.sh
```
To list the images stored locally and see both _fedora:latest_ and _myfedora:latest_ run:
```
$ sudo podman images
```
To run the _myFedora_ image as a container and get a bash prompt in the container run:
```
$ sudo podman run -ti -v /srv/repodir:/srv/repodir:Z myfedora /bin/bash
```
Podman also allows you to run containers rootless (as an unprivileged user). Run the script without _sudo_ to create the _myfedora_ image and store it in the unprivileged users image repository:
```
$ ./base-image-build.sh
```
In order to run the _myfedora_ image as a rootless container on a Fedora Linux host, an additional flag is needed. Without the extra flag, SELinux will block access to _/srv/repodir_ on the host.
```
$ podman run --security-opt label=disable -ti -v /srv/repodir:/srv/repodir:Z myfedora /bin/bash
```
By using this custom image as the base for your Fedora Linux containers, the iterative building and development of applications or services on them will be faster.
**Bonus Points** for even better _dnf_ performance, Dan Walsh describes how to share _dnf_ metadata between a host and container using a file overlay (see <https://www>. redhat.com/sysadmin/speeding-container-buildah). This technique will work in combination with a shared local repository only if the host and the container use the same local repository. The _dnf_ metadata cache includes metadata for the local repository under the name __dnf_local_.
I have created a container file that uses _buildah_ to do a _dnf_ update on a _fedora:latest_ image. Ive also created a container file to repeat the process using a _myfedora_ image. There are 53 MB and 111 rpms in the _dnf_ update. The only difference between the images is that _myfedora_ has the DNF local plugin installed. Using the local repository cut the elapse time by more than half in this example and saves 53MB of internet bandwidth consumption.
With the _fedora:latest_ image the command and elapsed time is:
```
# sudo time -f "Elapsed Time: %E" buildah bud -v /var/cache/dnf:/var/cache/dnf:O - f Containerfile.3 .
128 Elapsed Time: 0:48.06
```
With the _myfedora_ image the command and elapsed time is less than half of the base run. The **:Z** on the **-v** volume below is required when running the container on a SELinux-enabled host.
```
# sudo time -f "Elapsed Time: %E" buildah bud -v /var/cache/dnf:/var/cache/dnf:O -v /srv/repodir:/srv/repodir:Z -f Containerfile.4 .
133 Elapsed Time: 0:19.75
```
### Repository management
The local repository will accumulate files over time. Among the files will be many versions of rpms that change frequently. The kernel rpms are one such example. A system upgrade (for example upgrading from Fedora Linux 33 to Fedora Linux 34) will copy many rpms into the local repository. The _dnf repomanage_ command can be used to remove outdated rpm archives. I have not used the plugin long enough to explore this. The interested and knowledgeable reader is welcome to write an article about the _dnf repomanage_ command for Fedora Magazine.
Finally, I keep the _x86_64_ rpms for my workstation, virtual machines and containers in a local repository that is separate from the _aarch64_ local repository for the Raspberry Pis and (future) containers hosting my Kubernetes cluster. I have separated them for reasons of convenience and happenstance. A single repository location should work across all architectures.
### An important note about Fedora Linux system upgrades
Glenn Johnson has more than four years experience with the DNF local plugin. On occasion he has experienced problems when upgrading to a new release of Fedora Linux with the DNF local plugin enabled. Glenn strongly recommends that the _enabled_ attribute in the plugin configuration file _/etc/dnf/plugins/local.conf_ be set to **false** before upgrading your systems to a new Fedora Linux release. After the system upgrade, re-enable the plugin. Glenn also recommends using a separate local repository for each Fedora Linux release. For example, a NFS server might export _/volume1/dnf-repo/33_ for Fedora Linux 33 systems only. Glenn hangs out on fedoraforum.org an independent online resource for Fedora Linux users.
### Summary
The DNF local plugin has been beneficial to my ongoing work with a Fedora Linux based Kubernetes cluster. The containers and virtual machines running on my Fedora Linux desktop have also benefited. I appreciate how it supplements the existing DNF process and does not dictate any changes to how I update my systems or how I work with containers and virtual machines. I also appreciate not having to download the same set of rpms multiple times which saves me money, frees up bandwidth, and reduces the load on the Fedora Linux mirror hosts. Give it a try and see if the plugin will help in your situation!
Thanks to Glenn Johnson for his post on the DNF local plugin which started this journey, and for his helpful reviews of this post.
--------------------------------------------------------------------------------
via: https://fedoramagazine.org/use-the-dnf-local-plugin-to-speed-up-your-home-lab/
作者:[Brad Smith][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://fedoramagazine.org/author/buckaroogeek/
[b]: https://github.com/lujun9972
[1]: https://fedoramagazine.org/wp-content/uploads/2021/04/dnf-local-816x345.jpg
[2]: https://unsplash.com/@_s9h8_?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText
[3]: https://unsplash.com/?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText
[4]: https://dnf-plugins-core.readthedocs.io/en/latest/local.html
[5]: https://forums.fedoraforum.org/showthread.php?318812-dnf-plugin-local
[6]: https://fedoraproject.org/wiki/%20Infrastructure/Mirroring#How_can_someone_make_a_private_mirror
[7]: https://www.redhat.com/sysadmin/nfs-server-client
[8]: https://fedoramagazine.org/using-ansible-setup-workstation/
[9]: https://alt.fedoraproject.org/cloud/
[10]: https://vagrantup.com/
[11]: https://fedoramagazine.org/vagrant-qemukvm-fedora-devops-sysadmin/
[12]: https://github.com/buckaroogeek/dnf-local-plugin-examples/tree/main/vagrant-example
[13]: https://fedoramagazine.org/how-to-build-fedora-container-images/
[14]: https://github.com/buckaroogeek/dnf-local-plugin-examples/tree/main/container-example

View File

@@ -1,87 +0,0 @@
[#]: subject: (WASI, Bringing WebAssembly Way Beyond Browsers)
[#]: via: (https://www.linux.com/news/wasi-bringing-webassembly-way-beyond-browsers/)
[#]: author: (Dan Brown https://training.linuxfoundation.org/announcements/wasi-bringing-webassembly-way-beyond-browsers/)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
WASI, Bringing WebAssembly Way Beyond Browsers
======
_By Marco Fioretti_
[WebAssembly (Wasm)][1] is a binary software format that all browsers can run directly, [safely][2] and at near-native speeds, on any operating system (OS). Its biggest promise, however, is to eventually work in the same way [everywhere][3], from IoT devices and edge servers, to mobile devices and traditional desktops. This post introduces the main interface that should make this happen. The next post in this series will describe some of the already available, real-world implementations and applications of the same interface.
**What is portability, again?**
To be safe and portable, software code needs, as a minimum: 
1. guarantees that users and programs can do only what they actually _have_ the right to do, and only do it without creating problems to other programs or users
2. standard, platform-independent methods to declare and apply those guarantees
Traditionally, these services are provided by libraries of “system calls” for each language, that is functions with which a software program can ask its host OS to perform some low-level, or sensitive task. When those libraries follow standards like [POSIX][4], any compiler can automatically combine them with the source code, to produce a binary file that can run on _some_ combination of OSes and processors.
**The next level: BINARY compatibility**
System calls only make _source code_ portable across platforms. As useful as they are, they still force developers to generate platform-specific executable files, all too often from more or less different combinations of source code.
WebAssembly instead aims to get to the next level: use any language you want, then compile it once, to produce one binary file that will _just run_, securely, in any environment that recognizes WebAssembly. 
**What Wasm does not need to work outside browsers**
Since WebAssembly already “compiles once” for all major browsers, the easiest way to expand its reach may seem to create, for every target environment, a full virtual machine (runtime) that provides everything a Wasm module expects from Firefox or Chrome.
Work like that however would be _really_ complex, and above all simply unnecessary, if not impossible, in many cases (e.g. on IoT devices). Besides, there are better ways to secure Wasm modules than dumping them in one-size-fits-all sandboxes as browsers do today.
**The solution? A virtual operating system and runtime**
Fully portable Wasm modules cannot happen until, to give one practical example, accesses to webcams or websites can be written only with system calls that generate platform-dependent machine code.
Consequently, the most practical way to have such modules, from _any_ programming language, seems to be that of the [WebAssembly System interface (WASI) project][5]: write and compile code for only _one, obviously virtual,_ but complete operating system.
On one hand WASI gives to all the developers of [Wasm runtimes][6] one single OS to emulate. On the other, WASI gives to all programming languages one set of system calls to talk to that same OS.
In this way, even if you loaded it on ten different platforms, a _binary_ Wasm module calling a certain WASI function would still get from the runtime that launched it a different binary object every time. But since all those objects would interact with that single Wasm module in exactly the same way, it would not matter!
This approach would work also in the first use case of WebAssembly, that is with the JavaScript virtual machines inside web browsers. To run Wasm modules that use WASI calls, those machines should only load the JavaScript versions of the corresponding libraries.
This OS-level emulation is also more secure than simple sandboxing. With WASI, any runtime can implement different versions of each system call with different security privileges as long as they all follow the specification. Then that runtime could place every instance of every Wasm module it launches into a separate sandbox, containing only the smallest, and least privileged combination of functions that that specific instance really needs.
This “principle of least privilege”, or “[capability-based security model][7]“, is everywhere in WASI. A WASI runtime can pass into a sandbox an instance of the “open” system call that is only capable of opening the specific files, or folders, that were _pre-selected_ by the runtime itself. This is a more robust, much more granular control on what programs can do than it would be possible with traditional file permissions, or even with chroot systems.
Coding-wise, functions for things like basic management of files, folders, network connections or time are needed by almost any program. Therefore the corresponding WASI interfaces are designed as similar as possible to their POSIX equivalents, and all packaged into one “wasi-core” module, that every WASI-compliant runtime must contain.
A version of the [libc][8] standard C library, rewritten usi wasi-core functions, is already available and, [according to its developers][9], already “sufficiently stable and usable for many purposes”. 
All the other virtual interfaces that WASI includes, or will include over time, are standardized and packaged as separate modules,  without forcing any runtime to support all of them. In the next article we will see how some of these WASI components are already used today.
The post [WASI, Bringing WebAssembly Way Beyond Browsers][10] appeared first on [Linux Foundation Training][11].
--------------------------------------------------------------------------------
via: https://www.linux.com/news/wasi-bringing-webassembly-way-beyond-browsers/
作者:[Dan Brown][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://training.linuxfoundation.org/announcements/wasi-bringing-webassembly-way-beyond-browsers/
[b]: https://github.com/lujun9972
[1]: https://training.linuxfoundation.org/announcements/an-introduction-to-webassembly/
[2]: https://training.linuxfoundation.org/announcements/webassembly-security-now-and-in-the-future/
[3]: https://webassembly.org/docs/non-web/
[4]: https://www.gnu.org/software/libc/manual/html_node/POSIX.html#POSIX
[5]: https://hacks.mozilla.org/2019/03/standardizing-wasi-a-webassembly-system-interface/
[6]: https://github.com/appcypher/awesome-wasm-runtimes
[7]: https://github.com/WebAssembly/WASI/blob/main/docs/WASI-overview.md#capability-oriented
[8]: https://en.wikipedia.org/wiki/C_standard_library
[9]: https://github.com/WebAssembly/wasi-libc
[10]: https://training.linuxfoundation.org/announcements/wasi-bringing-webassembly-way-beyond-browsers/
[11]: https://training.linuxfoundation.org/

View File

@@ -1,101 +0,0 @@
[#]: subject: (How I digitized my CD collection with open source tools)
[#]: via: (https://opensource.com/article/21/4/digitize-cd-open-source-tools)
[#]: author: (Chris Hermansen https://opensource.com/users/clhermansen)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
How I digitized my CD collection with open source tools
======
Clean off your shelves by ripping your CDs and tagging them for easy
playback across your home network.
![11 CDs in a U shape][1]
The restrictions on getting out and about during the pandemic occasionally remind me that time is slipping by—although some days, "slipping" doesn't quite feel like the right word. But it also reminds me there are more than a few tasks around the house that can be great for restoring the sense of accomplishment that so many of us have missed.
One such task, in my home anyway, is converting our CD collection to [FLAC][2] and storing the files on our music server's hard drive. Considering we don't have a huge collection (at least, by some people's standards), I'm surprised we still have so many CDs awaiting conversion—even excluding all the ones that fail to impress and therefore don't merit the effort.
As for that ticking clock—who knows how much longer the CD player will continue working or the CD-ROM drive in the old computer will remain in service? Plus, I'd rather have the CDs shelved in the basement storage instead of cluttering up the family room.
So, here I sit on a rainy Sunday afternoon with a pile of classical music CDs, ready to go…
### Ripping CDs
I like using the open source [Asunder CD ripper][3]. It's a simple and straightforward tool that uses the [cdparanoia][4] tool to handle the conversion chores. This image shows it working away on an album.
![Asunder][5]
(Chris Hermansen, [CC BY-SA 4.0][6])
When I fired up Asunder, I was surprised that its Compact Disc Database (CDDB) lookup feature didn't seem to find any matching info. A quick online search led me to a Linux Mint forum discussion that [offered alternatives][7] for the freedb.freedb.org online service, which apparently is no longer working. I first tried using gnudb.gnudb.org with no appreciably better result; plus, the suggested link to gnudb.org/howto.php upset Firefox due to an expired certificate.
Next, I tried the freedb.freac.org service (note that it is on port 80, not 8880, as was freedb.freedb.org), which worked well for me… with one notable exception: The contributed database entries don't seem to understand the difference between "artist" (or "performer") and "composer." This isn't a huge problem for popular music, but having JS Bach as the "artist" seems a bit incongruous since he never made it to a recording studio, as far as I know.
Quite a few of the tracks I converted identified the composer in the track title, but if there's one thing I've learned, your metadata can never be too correct. This leads me to the issue of tag editing, or curating the collection.
Oh wait, there's another reason for tag editing, too, at least when using Asunder to rip: getting the albums' cover images.
### Editing tags and curating the collection
My open source go-to tool for [music tag editing continues to be EasyTag][8]. I use it a lot, both for downloads I purchase (it's amazing how messed up their tags can be, and some download services offer untagged WAV format files) and for tidying up the CDs I rip.
Take a look at what Asunder has (and hasn't) accomplished from EasyTag's perspective. One of the CDs I ripped included Ravel's _Daphnis et Chloé Suites 1 and 2_ and Strauss' _Don Quixote_. The freedb.freac.org database seemed to think that the composers Maurice Ravel and Richard Strauss were the artists performing the work, but the artist on this album is the wonderful London Symphony Orchestra led by André Previn. In Asunder, I clicked the "single artist" checkbox and changed the artist name to the LSO. Here's what it looks like in EasyTag:
![EasyTag][9]
(Chris Hermansen, [CC BY-SA 4.0][6])
It's not quite there! But in EasyTag, I can select the first six tracks, tagging the composer on all the files by clicking on that little "A" icon on the right of the Composer field:
![Editing tags in EasyTag][10]
(Chris Hermansen, [CC BY-SA 4.0][6])
I can set the remaining 13 similarly, then select the whole lot and set the Album Artist as well. Finally, I can flip to the Images tab and find and set the album cover image.
Speaking of images, I've found it wise to always name the image "cover.jpg" and make sure it's in the directory with the FLAC files… some players aren't happy with PNG files, some want the file in the same directory, and some are just plain difficult to get along with, as far as images go.
What is your favorite open source CD ripping tool? How about the open source tool you like to use to fix your metadata? Let me know in the comments below!
### And speaking of music…
I haven't been as regular with my music and open source column over the past year as I was in previous years. Although I didn't acquire a lot of new music in 2020 and 2021, a few jewels still came my way…
As always, [Erased Tapes][11] continues to develop an amazing collection of hmmm… what would you call it, anyway? The site uses the terms "genre-defying" and "avant-garde," which don't seem overblown for once. A recent favorite is Rival Consoles' [_Night Melody Articulation_][12], guaranteed to transport me from the day-to-day grind to somewhere else.
I've been a huge fan of [Gustavo Santaolalla][13] since I first heard his music on a road trip from Coyhaique to La Tapera in Chile's Aysén Region. You might be familiar with his film scores to _Motorcycle Diaries_ or _Brokeback Mountain_. I recently picked up [_Qhapaq Ñan_, music about the Inca Trail][14], on the Linux-friendly music site [7digital][15], which has a good selection of his work.
Finally, and continuing with the Latin American theme, The Queen's Six recording [_Journeys to the New World_][16] is not to be missed. It is available in FLAC format (including high-resolution versions) from the Linux-friendly [Signum Classics][17] site.
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/4/digitize-cd-open-source-tools
作者:[Chris Hermansen][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/clhermansen
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/life_cd_dvd.png?itok=RBwVIzmi (11 CDs in a U shape)
[2]: https://en.wikipedia.org/wiki/FLAC
[3]: https://opensource.com/article/17/2/open-music-tagging
[4]: https://www.xiph.org/paranoia/
[5]: https://opensource.com/sites/default/files/uploads/asunsder.png (Asunder)
[6]: https://creativecommons.org/licenses/by-sa/4.0/
[7]: https://forums.linuxmint.com/viewtopic.php?t=322415
[8]: https://opensource.com/article/17/5/music-library-tag-management-tools
[9]: https://opensource.com/sites/default/files/uploads/easytag.png (EasyTag)
[10]: https://opensource.com/sites/default/files/uploads/easytag_editing-tags.png (Editing tags in EasyTag)
[11]: https://www.erasedtapes.com/about
[12]: https://www.erasedtapes.com/release/eratp139-rival-consoles-night-melody-articulation
[13]: https://en.wikipedia.org/wiki/Gustavo_Santaolalla
[14]: https://ca.7digital.com/artist/gustavo-santaolalla/release/qhapaq-%C3%B1an-12885504?f=20%2C19%2C12%2C16%2C17%2C9%2C2
[15]: https://ca.7digital.com/search/release?q=gustavo%20santaolalla&f=20%2C19%2C12%2C16%2C17%2C9%2C2
[16]: https://signumrecords.com/product/journeys-to-the-new-world-hispanic-sacred-music-from-the-16th-17th-centuries/SIGCD626/
[17]: https://signumrecords.com/

View File

@@ -1,181 +0,0 @@
[#]: subject: (Hyperbola Linux Review: Systemd-Free Arch With Linux-libre Kernel)
[#]: via: (https://itsfoss.com/hyperbola-linux-review/)
[#]: author: (Sarvottam Kumar https://itsfoss.com/author/sarvottam/)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
Hyperbola Linux Review: Systemd-Free Arch With Linux-libre Kernel
======
In the last month of 2019, the Hyperbola project took a [major decision][1] of ditching Linux in favor of OpenBSD. We also had a [chat][2] with Hyperbola co-founder Andre Silva, who detailed the reason for dropping Hyperbola OS and starting a new HyperbolaBSD.
HyperbolaBSD is still under development and its alpha release will be ready by September 2021 for initial testing. The current Hyperbola GNU/Linux-libre v0.3.1 Milky Way will be supported until the legacy [Linux-libre kernel][3] reaches the end of life in 2022.
I thought of giving it a try before it goes away and switches to BSD completely.
### What is Hyperbola GNU/Linux-libre?
![][4]
Back in April 2017, the Hyperbola project was started by its [six co-founders][5] with an aim to deliver a lightweight, stable, secure, software freedom, and privacy focussed operating system. 
Subsequently, the first stable version of Hyperbola GNU/Linux-libre arrived in July 2017. It was based on Arch Linux snapshots combining Debian development.
But, unlike Arch having a rolling release model, Hyperbola GNU/Linux-libre follows a Long Term Support (LTS) model.
Also, instead of a generic Linux kernel, it includes GNU operating system components and the Linux-libre kernel. Most importantly, Hyperbola is also one of the distributions without Systemd init system.
Even though the Systemd is widely adopted by major Linux distributions like Ubuntu, Hyperbola replaced it with OpenRC as the default init system. v0.1 of Hyperbola was the first and the last version to support Systemd.
Moreover, Hyperbola put high emphasis on Keep It Simple Stupid (KISS) methodology. It provides packages for i686 and x86_64 architecture that meets GNU Free System Distribution Guidelines (GNU FSDG).
Not just that, but it also has its own social contract and packaging guidelines that follow the philosophy of the Free Software Movement.
Hence, Free Software Foundation [recognized][6] Hyperbola GNU/Linux-libre as the first completely free Brazilian operating system in 2018.
### Downloading Hyperbola GNU/Linux-libre 0.3.1 Milky Way
The hyperbola project provides [two live images][7] for installation: one is the regular Hyperbola and the other is Hypertalking. Hypertalking is the ISO optimized and adapted for blind and visually impaired users.
Interestingly, if you already use Arch Linux or Arch-based distribution like Parabola, you dont need to download a live image. You can easily migrate to Hyperbola by following the official [Arch][8] or [Parabola][9] migration guide.
The ISO image sizes around 650MB containing only essential packages (excluding desktop environment) to boot only in a command line interface.
### Hardware requirements for Hyperbola
For v0.3.1 (x86_64), you require a minimum of any 64-bit processor, 47MiB (OS installed) and 302MiB (Live image) of RAM for text mode only with no desktop environment.
While for v0.3.1 (i686), you require a minimum of Intel Pentium II or AMD Athlon CPU model, 33MiB (OS installed), and 252MiB (Live image) of RAM for text mode only with no desktop environment.
### Installing Hyperbola Linux from scratch
Currently, I dont use Arch or Parabola distribution. Hence, instead of migration, I chose to install Hyperbola Linux from scratch.
I also mostly dont dual boot unknown (to me) distribution on my hardware as it may create undetermined problems. So, I decided to use the wonderful GNOME Boxes app for setting up a Hyperbola virtual machine with up to 2 GB of RAM and 22 GB of free disk space.
Similar to Arch, Hyperbola also does not come with a graphical user interface (GUI) installer. It means you need to set up almost everything from scratch using a command line interface (CLI).
Here, it also concludes that Hyperbola is definitely not for beginners and those afraid of the command line.
However, Hyperbola does provide separate [installation instruction][10], especially for beginners. But I think it still misses several steps that can trouble beginners during the installation process.
For instance, it does not guide you to connect to the network, set up a new user account, and install a desktop environment.
Hence, there is also another Hyperbola [installation guide][11] that you need to refer to in case youre stuck at any step.
As I booted the live image, the boot menu showed the option to install for both 64-bit or 32-bit architecture.
![Live Image Boot Menu][12]
Next, following the installation instruction, I went through setting up disk partition, DateTime, language, and password for the root user.
![Disk partition][13]
Once everything set up, I then installed the most common [Grub bootloader][14] and rebooted the system. Phew! until now, all went well as I could log in to my Hyperbola system.
![text mode][15]
### Installing Xfce desktop in Hyperbola Linux
The command-line interface was working fine for me. But now, to have a graphical user interface, I need to manually choose and install a new [desktop environment][16] as Hyperbola does not come with any default DE.
For the sake of simplicity and lightweight, I chose to get the popular [Xfce desktop][17]. But before installing it, I also needed a Xorg [display server][18]. So, I installed it along with other important packages using the default pacman package manager.
![Install X.Org][19]
Later, I installed LightDM cross-desktop [display manager][20], Xfce desktop, and other necessary packages like elogind for managing user logins.
![Install Xfce desktop environment][21]
After the Xfce installation, you also need to add LightDM service at the default run level to automatically switch to GUI mode. You can use the below command and reboot the system:
```
rc-update add lightdm default
reboot
```
![Add LightDM at runlevel][22]
#### Pacman Signature Error In Hyperbola Linux
While installing Xorg and Xfce in the latest Hyperbola v0.3.1, I encountered the signature error for some packages showing “signature is marginal trust” or “invalid or corrupted package.”
![Signature Error In Hyperbola Linux][23]
After searching the solution, I came to know from Hyperbola [Forum][24] that the main author Emulatormans keys expired on 1st Feb 2021.
Hence, until the author upgrades the key or a new version 0.4 arrives sooner or later, you can change the `SigLevel` from “SigLevel=Required DatabaseOptional” to “SigLevel=Never” in`/etc/pacman.conf` file to avoid this error.
![][25]
### Hyperbola Linux with Xfce desktop
![Hyperbola Linux With Xfce desktop][26]
Hyperbola GNU/Linux-libre with Xfce 4.12 desktop gives a very clean, light, and smooth user experience. At the core, it contains Linux-libre 4.9 and OpenRC 0.28 service manager.
![][27]
As Hyperbola does not come with customized desktops and tons of bloated software, it definitely gives flexibility and freedom to choose, install, and configure the services you want.
On the memory usage side, it takes around 205MB of RAM (approx. 10%) while running no applications (except terminal).
![][28]
### Is Hyperbola a suitable distribution for you?
As per my experience, it definitely not a [Linux distribution that I would like to suggest to complete beginners][29]. Well, the Hyperbola project does not even claim to be beginners-friendly.
If youre well-versed with the command line and have quite a good knowledge of Linux concepts like disk partition, you can give it a try and decide yourself. Spending time hacking around the installation and configuration process can teach you a lot.
Another thing that might matter in choosing Hyperbola Linux is also the default init system. If youre looking for Systemd-free distribution with complete customization control from scratch, what can be better than it.
Last but not least, you should also consider the future of Hyperbola, which will no longer contain Linux Kernel as it will turn into a HyperbolaBSD with OpenBSD Linux and userspace.
If youve already tried or currently using Hyperbola Linux, let us know your experience in the comment below.
--------------------------------------------------------------------------------
via: https://itsfoss.com/hyperbola-linux-review/
作者:[Sarvottam Kumar][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/sarvottam/
[b]: https://github.com/lujun9972
[1]: https://www.hyperbola.info/news/announcing-hyperbolabsd-roadmap/
[2]: https://itsfoss.com/hyperbola-linux-bsd/
[3]: https://www.fsfla.org/ikiwiki/selibre/linux-libre/
[4]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/04/hyperbola-gnu-linux.png?resize=800%2C450&ssl=1
[5]: https://www.hyperbola.info/members/founders/
[6]: https://www.fsf.org/news/fsf-adds-hyperbola-gnu-linux-libre-to-list-of-endorsed-gnu-linux-distributions
[7]: https://wiki.hyperbola.info/doku.php?id=en:main:downloads&redirect=1
[8]: https://wiki.hyperbola.info/doku.php?id=en:migration:from_arch
[9]: https://wiki.hyperbola.info/doku.php?id=en:migration:from_parabola
[10]: https://wiki.hyperbola.info/doku.php?id=en:guide:beginners
[11]: https://wiki.hyperbola.info/doku.php?id=en:guide:installation
[12]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/04/Live-Image-Boot-Menu.png?resize=640%2C480&ssl=1
[13]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/04/Disk-partition.png?resize=600%2C450&ssl=1
[14]: https://itsfoss.com/what-is-grub/
[15]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/04/text-mode.png?resize=600%2C450&ssl=1
[16]: https://itsfoss.com/what-is-desktop-environment/
[17]: https://xfce.org/
[18]: https://itsfoss.com/display-server/
[19]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/04/Install-xorg-package.png?resize=600%2C450&ssl=1
[20]: https://itsfoss.com/display-manager/
[21]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/04/Install-Xfce-desktop-environment-800x600.png?resize=600%2C450&ssl=1
[22]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/04/Add-LightDM-at-runlevel.png?resize=600%2C450&ssl=1
[23]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/04/Signature-Error-In-Hyperbola-Linux.png?resize=600%2C450&ssl=1
[24]: https://forums.hyperbola.info/viewtopic.php?id=493
[25]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2021/04/Configure-pacman-SigLevel.png?resize=600%2C450&ssl=1
[26]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/04/Hyperbola-Linux-With-Xfce-desktop.jpg?resize=800%2C450&ssl=1
[27]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2021/04/Hyperbola-System-Information.jpg?resize=800%2C450&ssl=1
[28]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2021/04/Memory-Usage.jpg?resize=800%2C450&ssl=1
[29]: https://itsfoss.com/best-linux-beginners/

View File

@@ -1,133 +0,0 @@
[#]: subject: (In the trenches with Thomas Gleixner, real-time Linux kernel patch set)
[#]: via: (https://www.linux.com/news/in-the-trenches-with-thomas-gleixner-real-time-linux-kernel-patch-set/)
[#]: author: (Linux.com Editorial Staff https://www.linux.com/author/linuxdotcom/)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
In the trenches with Thomas Gleixner, real-time Linux kernel patch set
======
_![][1]_
_Jason Perlow, Editorial Director at the Linux Foundation interviews Thomas Gleixner, Linux Foundation Fellow, CTO of Linutronix GmbH, and project leader of the_ [_PREEMPT_RT_][2] _real-time kernel patch set._
**JP:** *Greetings, Thomas! Its great to have you here this morning — although for you, its getting late in the afternoon in Germany. So **PREEMPT_RT**, the real-time patch set for the kernel is a fascinating project because it has some very important use-cases that most people who use Linux-based systems may not be aware of. First of all, can you tell me what “Real-Time” truly means? *
**TG:** Real-Time in the context of operating systems means that the operating system provides mechanisms to guarantee that the associated real-time task processes an event within a specified period of time. Real-Time is often confused with “really fast.” The late Prof. Doug Niehaus explained it this way: “Real-Time is not as fast as possible; it is as fast as specified.”
The specified time constraint is application-dependent. A control loop for a water treatment plant can have comparatively large time constraints measured in seconds or even minutes, while a robotics control loop has time constraints in the range of microseconds. But for both scenarios missing the deadline at which the computation has to be finished can result in malfunction. For some application scenarios, missing the deadline can have fatal consequences.
In the strict sense of Real-Time, the guarantee which is provided by the operating system must be verifiable, e.g., by mathematical proof of the worst-case execution time. In some application areas, especially those related to functional safety (aerospace, medical, automation, automotive, just to name a few), this is a mandatory requirement. But for other scenarios or scenarios where there is a separate mechanism for providing the safety requirements, the proof of correctness can be more relaxed. But even in the more relaxed case, the malfunction of a real-time system can cause substantial damage, which obviously wants to be avoided.
**JP:** _What is the history behind the project? How did it get started?_
**TG:** Real-Time Linux has a history that goes way beyond the actual **PREEMPT_RT** project.
Linux became a research vehicle very early on. Real-Time researchers set out to transform Linux into a Real-Time Operating system and followed different approaches with more or less success. Still, none of them seriously attempted a fully integrated and perhaps upstream-able variant. In 2004 various parties started an uncoordinated effort to get some key technologies into the Linux kernel on which they wanted to build proper Real-Time support. None of them was complete, and there was a lack of an overall concept. 
Ingo Molnar, working for RedHat, started to pick up pieces, reshape them and collect them in a patch series to build the grounds for the real-time preemption patch set **PREEMPT_RT**. At that time, I worked with [the late Dr. Doug Niehaus][3] to port a solution we had working based on the 2.4 Linux kernel forward to the 2.6 kernel. Our work was both conflicting and complimentary, so I teamed up with Ingo quickly to get this into a usable shape. Others like Steven Rostedt brought in ideas and experience from other Linux Real-Time research efforts. With a quickly forming loose team of interested developers, we were able to develop a halfway usable Real-Time solution that was fully integrated into the Linux kernel in a short period of time. That was far from a maintainable and production-ready solution. Still, we had laid the groundwork and proven that the concept of making the Linux Kernel real-time capable was feasible. The idea and intent of fully integrating this into the mainline Linux kernel over time were there from the very beginning.
**JP:** _Why is it still a separate project from the Mainline kernel today?_
**TG:** To integrate the real-time patches into the Linux kernel, a lot of preparatory work, restructuring, and consolidation of the mainline codebase had to be done first. While many pieces that emerged from the real-time work found their way into the mainline kernel rather quickly due to their isolation, the more intrusive changes that change the Linux kernels fundamental behavior needed (and still need) a lot of polishing and careful integration work. 
Naturally, this has to be coordinated with all the other ongoing efforts to adopt the Linux kernel to the different use cases ranging from tiny embedded systems to supercomputers. 
This also requires carefully designing the integration so it does not get in the way of other interests and imposes roadblocks for further developing the Linux kernel, which is something the community and especially Linus Torvalds, cares about deeply. 
As long as these remaining patches are out of the mainline kernel, this is not a problem because it does not put any burden or restriction on the mainline kernel. The responsibility is on the real-time project, but on the other side, in this context, there is no restriction to take shortcuts that would never be acceptable in the upstream kernel.
The real-time patches are fundamentally different from something like a device driver that sits at some corner of the source tree. A device driver does not cause any larger damage when it goes unmaintained and can be easily removed when it reaches the final state bit-rot. Conversely, the **PREEMPT_RT** core technology is in the heart of the Linux kernel. Long-term maintainability is key as any problem in that area will affect the Linux user universe as a whole. In contrast, a bit-rotted driver only affects the few people who have a device depending on it.
**JP:** *Traditionally, when I think about RTOS, I think of legacy solutions based on closed systems. Why is it essential we have an open-source alternative to them? *
**TG:** The RTOS landscape is broad and, in many cases, very specialized. As I mentioned on the question of “what is real-time,” certain application scenarios require a fully validated RTOS, usually according to an application space-specific standard and often regulatory law. Aside from that, many RTOSes are limited to a specific class of CPU devices that fit into the targeted application space. Many of them come with specialized application programming interfaces which require special tooling and expertise.
The Real-Time Linux project never aimed at these narrow and specialized application spaces. It always was meant to be the solution for 99% of the use cases and to be able to fully leverage the flexibility and scalability of the Linux kernel and the broader FOSS ecosystem so that integrated solutions with mixed-criticality workloads can be handled consistently. 
Developing real-time applications on a real-time enabled Linux kernel is not much different from developing non-real-time applications on Linux, except for the careful selection of system interfaces that can be utilized and programming patterns that should be avoided, but that is true for real-time application programming in general independent of the RTOS. 
The important difference is that the tools and concepts are all the same, and integration into and utilizing the larger FOSS ecosystem comes for free.
The downside of **PREEMPT_RT** is that it cant be fully validated, which excludes it from specific application spaces, but there are efforts underway, e.g., the LF ELISA project, to fill that gap. The reason behind this is, that large multiprocessor systems have become a commodity, and the need for more complex real-time systems in various application spaces, e.g., assisted / autonomous driving or robotics, requires a more flexible and scalable RTOS approach than what most of the specialized and validated RTOSes can provide. 
Thats a long way down the road. Still, there are solutions out there today which utilize external mechanisms to achieve the safety requirements in some of the application spaces while leveraging the full potential of a real-time enabled Linux kernel along with the broad offerings of the wider FOSS ecosystem.
**JP:** _What are examples of products and systems that use the real-time patch set that people depend on regularly?_
**TG:** Its all over the place now. Industrial automation, control systems, robotics, medical devices, professional audio, automotive, rockets, and telecommunication, just to name a few prominent areas.
**JP:** *Who are the major participants currently developing systems and toolsets with the real-time Linux kernel patch set?  *
**TG:** Listing them all would be equivalent to reciting the “whos who” in the industry. On the distribution side, there are offerings from, e.g., RedHat, SUSE, Mentor, and Wind River, which deliver RT to a broad range of customers in different application areas. There are firms like Concurrent, National Instruments, Boston Dynamics, SpaceX, and Tesla, just to name a few on the products side.
RedHat and National Instruments are also members of the LF collaborative Real-Time project.
**JP:** _What are the challenges in developing a real-time subsystem or specialized kernel for Linux? Is it any different than how other projects are run for the kernel?_
**TG:** Not really different; the same rules apply. Patches have to be posted, are reviewed, and discussed. The feedback is then incorporated. The loop starts over until everyone agrees on the solution, and the patches get merged into the relevant subsystem tree and finally end up in the mainline kernel.
But as I explained before, it needs a lot of care and effort and, often enough, a large amount of extra work to restructure existing code first to get a particular piece of the patches integrated. The result is providing the desired functionality but is at the same time not in the way of other interests or, ideally, provides a benefit for everyone.
The technologys complexity that reaches into a broad range of the core kernel code is obviously challenging, especially combined with the mainline kernels rapid change rate. Even larger changes happening at the related core infrastructure level are not impacting ongoing development and integration work too much in areas like drivers or file systems. But any change on the core infrastructure can break a carefully thought-out integration of the real-time parts into that infrastructure and send us back to the drawing board for a while.
**JP:**  *Which companies have been supporting the effort to get the **PREEMPT_RT** Linux kernel patches upstream? *
**TG:** For the past five years, it has been supported by the members of the LF real-time Linux project, currently ARM, BMW, CIP, ELISA, Intel, National Instruments, OSADL, RedHat, and Texas Instruments. CIP, ELISA, and OSADL are projects or organizations on their own which have member companies all over the industry. Former supporters include Google, IBM, and NXP.
I personally, my team and the broader Linux real-time community are extremely grateful for the support provided by these members. 
However, as with other key open source projects heavily used in critical infrastructure, funding always was and still is a difficult challenge. Even if the amount of money required to keep such low-level plumbing but essential functionality sustained is comparatively small, these projects struggle with finding enough sponsors and often lack long-term commitment.
The approach to funding these kinds of projects reminds me of the [Mikado Game][4], which is popular in Europe, where the first player who picks up the stick and disturbs the pile often is the one who loses.
Thats puzzling to me, especially as many companies build key products depending on these technologies and seem to take the availability and sustainability for granted up to the point where such a project fails, or people stop working on it due to lack of funding. Such companies should seriously consider supporting the funding of the Real-Time project.
Its a lot like the [Jenga][5] game, where everyone pulls out as many pieces as they can up until the point where it collapses. We cannot keep taking; we have to give back to these communities putting in the hard work for technologies that companies heavily rely on.
I gave up long ago trying to make sense of that, especially when looking at the insane amounts of money thrown at the over-hyped technology of the day. Even if critical for a large part of the industry, low-level infrastructure lacks the buzzword charm that attracts attention and makes headlines — but it still needs support.
**JP:**  *One of the historical concerns was that Real-Time didnt have a community associated with it; what has changed in the last five years?  *
**TG:** There is a lively user community, and quite a bit of the activity comes from the LF project members. On the development side itself, we are slowly gaining more people who understand the intricacies of **PREEMPT_RT** and also people who look at it from other angles, e.g., analysis and instrumentation. Some fields could be improved, like documentation, but there is always something that can be improved.
**JP:**  _What will the Real-Time Stable team be doing once the patches are accepted upstream?_
**TG:** The stable team is currently overseeing the RT variants of the supported mainline stable versions. Once everything is integrated, this will dry out to some extent once the older versions reach EOL. But their expertise will still be required to keep real-time in shape in mainline and in the supported mainline stable kernels.
**JP:** _So once the upstreaming activity is complete, what happens afterward?_
**TG:** Once upstreaming is done, efforts have to be made to enable RT support for specific Linux features currently disabled on real-time enabled kernels. Also, for quite some time, there will be fallout when other things change in the kernel, and there has to be support for kernel developers who run into the constraints of RT, which they did not have to think about before. 
The latter is a crucial point for this effort. Because there needs to be a clear longer-term commitment that the people who are deeply familiar with the matter and the concepts are not going to vanish once the mainlining is done. We cant leave everybody else with the task of wrapping their brains around it in desperation; there cannot be institutional knowledge loss with a system as critical as this. 
The lack of such a commitment would be a showstopper on the final step because we are now at the point where the notable changes are focused on the real-time only aspects rather than welcoming cleanups, improvements, and features of general value. This, in turn, circles back to the earlier question of funding and industry support — for this final step requires several years of commitment by companies using the real-time kernel.
Theres not going to be a shortage of things to work on. Its not going to be as much as the current upstreaming effort, but as the kernel never stops changing, this will be interesting for a long time.
**JP:** _Thank you, Thomas, for your time this morning. Its been an illuminating discussion._
_To get involved with the real-time kernel patch for Linux, please visit the_ [_PREEMPT_RT wiki_][2] _at The Linux Foundation or email [real-time-membership@linuxfoundation.org][6]_
--------------------------------------------------------------------------------
via: https://www.linux.com/news/in-the-trenches-with-thomas-gleixner-real-time-linux-kernel-patch-set/
作者:[Linux.com Editorial Staff][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.linux.com/author/linuxdotcom/
[b]: https://github.com/lujun9972
[1]: https://www.linux.com/wp-content/uploads/2021/04/IntheTrenches_ThomasGleixner.png
[2]: https://wiki.linuxfoundation.org/realtime/start
[3]: https://lwn.net/Articles/514182/?fbclid=IwAR1mhNcOVlNdQ_QmwOhC1vG3vHzxsXRwa_g4GTo62u1sHbjOZBPPviT5bxc
[4]: https://en.wikipedia.org/wiki/Mikado_(game)
[5]: https://en.wikipedia.org/wiki/Jenga
[6]: mailto:real-time-membership@linuxfoundation.org

View File

@@ -1,141 +0,0 @@
[#]: subject: (How I use OBS Studio to record videos for my YouTube channel)
[#]: via: (https://opensource.com/article/21/4/obs-youtube)
[#]: author: (Jim Hall https://opensource.com/users/jim-hall)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
How I use OBS Studio to record videos for my YouTube channel
======
Install, configure, and use Open Broadcaster Software to record how-to,
promotional, and other types of videos.
![Person using a laptop][1]
I manage a [YouTube channel for the FreeDOS Project][2], where I record "how-to" videos with FreeDOS running inside the [QEMU][3] PC emulator software. When I started the channel in August 2019, I didn't know anything about recording videos. But with [Open Broadcaster Software][4], also called OBS Studio, I've found recording these videos to be pretty straightforward. Here's how you can do it, too.
### Install OBS Studio
I run Fedora Linux, which doesn't include the OBS Studio software by default. Fortunately, the OBS Studio website has an [installation guide][5] that walks you through the steps to install OBS Studio via the RPM Fusion alternative repository.
If you don't already have RPM Fusion set up on your system, you can add the repository on Fedora using this one-line command:
```
`$ sudo dnf install https://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm https://download1.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-$(rpm -E %fedora).noarch.rpm`
```
Once the RPM Fusion repo is set up, you can install OBS Studio with this command:
```
`$ sudo dnf install obs-studio`
```
If you have an NVIDIA graphics card, there's an extra step in the installation guide to install hardware-accelerated video support. But my graphics card is from Intel, so I don't need to run the extra steps.
However, OBS Studio does not support [Wayland][6], at least not in the Fedora build. That means when I want to record videos with OBS Studio, I need to log into my GNOME desktop [using an Xorg session][7]. On the login screen, enter your password, click on the gear-shaped icon in the lower-right corner, and select **GNOME on Xorg**.
### Configure OBS Studio
The first time you launch OBS Studio, the software runs an auto-configuration wizard to determine the best settings for recording videos. This makes setup a breeze. If you're recording videos on the desktop, like I am, then click the **Optimize just for recording** radio button and click **Next**.
![OBS Studio configuration][8]
(Jim Hall, [CC BY-SA 4.0][9])
OBS Studio will run through a series of automated tests before it confirms the best video settings for your system. On my system, that's 1920x1080 at 30 frames per second (fps), which is good enough for recording my videos.
![OBS Studio configuration][10]
(Jim Hall, [CC BY-SA 4.0][9])
#### My setup
The default OBS Studio interface shows the video front and center and positions the controls at the bottom of the screen. While this is not a bad default arrangement, you can see in my early videos that I occasionally look away from the camera as I change from a full-screen webcam video to my QEMU screen. That's because the default OBS Studio configuration places the **Scene controls** in the lower-left corner.
![OBS Studio configuration][11]
(Jim Hall, [CC BY-SA 4.0][9])
Breaking virtual eye contact like this is distracting, so I wanted another way to change scenes without looking for the scene controls. I discovered that I could click and drag the OBS Studio controls to different areas on the screen. By positioning the scene controls at the top of the screen, near my computer's webcam, I don't need to look away from the camera to change scenes.
![OBS Studio configuration][12]
(Jim Hall, [CC BY-SA 4.0][9])
So, my first step whenever I set up OBS Studio is to drag the controls to the top of the screen. I like to place the **Scene selector panel** in the middle, so I don't have to look very far away from my camera to change scenes. I keep the recording controls to one side because I'm never on camera when I start or stop the video, so it doesn't matter if I look away to start or stop my video recording.
![OBS Studio configuration][13]
(Jim Hall, [CC BY-SA 4.0][9])
### Setting up scenes
You can set up OBS Studio to support your preferred video style. When I started recording videos, I watched other how-to videos to see how they were organized. Most start with a brief introduction by the host, then switch to a hands-on demonstration, and end with a "thank you" screen to advertise the channel. I wanted to create my videos similarly, and you can do that with scenes.
Each scene is a different arrangement of **sources**, or elements in the video. Each source is like a layer, so if you have multiple image or video sources, they will appear to stack on top of one another.
How you define your scenes depends on the kind of video you want to make. I do a lot of hands-on demonstration videos, so I have one scene with a full-screen webcam video, another scene that's just a QEMU window, and yet another scene that's "picture-in-picture" with me over my QEMU screen. I can also set up separate scenes that show a "thank you" image and links to subscribe to my channel or to join the project on social media.
With these scenes, I can record my videos as Live—meaning I don't need to edit them afterward. I can use the Scene controls in OBS Studio to switch from the **QEMU** scene to the **Full-screen webcam** screen and back to the **QEMU** screen before wrapping up with separate scenes that thank my supporters and share information about my channel. That may sound like a lot of work, but once you have the scenes set up, changing scenes is just clicking an item in the Scenes menu. That's why I like to center the Scene selector at the top of the screen, so I can easily select the scene I need.
Here's what I use to record my videos and how I set up the sources in each:
* **Full-screen webcam:** I set up a webcam source from my Vitade webcam as a **video capture device** (V4L) and use the **Transform** menu (right-click) to fit the webcam to the screen. This also uses my Yeti microphone for sound as an **audio input capture** (PulseAudio).
* **QEMU:** This is where I spend most of my time in my videos. OBS Studio can use any window as a source, and I define my QEMU window as a **window capture** (Xcomposite) source. In case I need to reboot the virtual machine while I'm recording a video, I also set a Color Bars image as a background image on a layer that's "behind" the window. This also uses my Yeti microphone for sound as an **audio input capture** (PulseAudio).
* **QEMU + webcam:** My viewers tell me they like to see me on camera while I'm showing things in my QEMU window, so I defined another scene that combines the **QEMU** and **Full-screen webcam** scenes. My webcam is a small rectangle in one corner of the screen.
* **Patreon card:** At the end of my videos, I thank the people who support me on Patreon. I created a striped pattern in GIMP and set that as my background image. I then defined a **text** source where I entered a "thank you" message and a list of my patrons. As before, I set my Yeti microphone for sound as an **audio input capture** (PulseAudio).
* **End card:** As I wrap up the video, I want to encourage viewers to visit our website or join us on social media. Similar to the Patreon card scene, I use a background pattern that already includes my text and icons. But to add a little visual flair, I created a blinking cursor after our URL, as though someone had typed it in. This cursor is not actually an animation but an **image slideshow** source that uses two images: a blank rectangle and a rectangle with a cursor. The image slideshow flips between these two images, creating the appearance of a blinking cursor.
![OBS Studio configuration][14]
(Jim Hall, [CC BY-SA 4.0][9])
### And action!
Once I create my scene collection, I'm ready to record my videos. I usually start by talking over my QEMU window, so I click on the **QEMU** scene and then click the **Start Recording** button. After I've said a few words to set the stage for my video, I click on the **Full-screen webcam** scene to fully introduce the topic.
After sharing some information about whatever I'm talking about in the video, I click on the **QEMU** scene or the **QEMU + webcam** scene. Which scene I choose depends on whether I need to be seen during the video or if the "picture-in-picture" video will obscure important text on the screen. I spend most of the how-to video in this scene, usually while playing a game, demonstrating a program, or writing a sample program.
When I'm ready to wrap up, I click on the **Patreon card** scene to thank everyone who supports me on Patreon. Some patrons support me at a higher level, and they get a specific mention and their name listed on the screen. Then, I click on the **End card** scene to encourage viewers to visit our website, join us on Facebook, follow us on Twitter, and consider supporting me on Patreon. Finally, I click the **Stop Recording** button, and OBS Studio stops the video.
Using OBS Studio is a great way to record videos. I've used this same method to record other videos, including pre-recorded conference talks, welcome videos for a remote symposium, and virtual lecture videos when I teach an online class.
The next time you need to record a video, try OBS Studio. I think you'll find it easy to learn and use.
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/4/obs-youtube
作者:[Jim Hall][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/jim-hall
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/laptop_screen_desk_work_chat_text.png?itok=UXqIDRDD (Person using a laptop)
[2]: https://www.youtube.com/freedosproject
[3]: https://www.qemu.org/
[4]: https://obsproject.com/
[5]: https://obsproject.com/wiki/install-instructions#linux
[6]: https://wayland.freedesktop.org/
[7]: https://docs.fedoraproject.org/en-US/quick-docs/configuring-xorg-as-default-gnome-session/
[8]: https://opensource.com/sites/default/files/uploads/obs-setup-02.png (OBS Studio configuration)
[9]: https://creativecommons.org/licenses/by-sa/4.0/
[10]: https://opensource.com/sites/default/files/uploads/obs-setup-09.png (OBS Studio configuration)
[11]: https://opensource.com/sites/default/files/uploads/obs-setup-10.png (OBS Studio configuration)
[12]: https://opensource.com/sites/default/files/uploads/obs-setup-11.png (OBS Studio configuration)
[13]: https://opensource.com/sites/default/files/uploads/obs-setup-12.png (OBS Studio configuration)
[14]: https://opensource.com/sites/default/files/uploads/obs-setup-18.png (OBS Studio configuration)

View File

@@ -1,196 +0,0 @@
[#]: subject: (Exploring the world of declarative programming)
[#]: via: (https://fedoramagazine.org/exploring-the-world-of-declarative-programming/)
[#]: author: (pampelmuse https://fedoramagazine.org/author/pampelmuse/)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
Exploring the world of declarative programming
======
![][1]
Photo by [Stefan Cosma][2] on [Unsplash][3]
### Introduction
Most of us use imperative programming languages like C, Python, or Java at home. But the universe of programming languages is endless and there are languages where no imperative command has gone before. That which may sound impossible at the first glance is feasible with Prolog and other so called declarative languages. This article will demonstrate how to split a programming task between Python and Prolog.
In this article I do not want to teach Prolog. There are [resources available][4] for that. We will demonstrate how simple it is to solve a puzzle solely by describing the solution. After that it is up to the reader how far this idea will take them.
To proceed, you should have a basic understanding of Python. Installation of Prolog and the Python-Prolog bridge is accomplished using this command:
dnf install pl python3-pyswip
Our exploration uses [SWI-Prolog][5], an actively developed Prolog which has the Fedora package name “pl”. The Python/SWI-Prolog bridge is [pyswip][6].
If you are a bold adventurer you are welcome to follow me exploring the world of declarative programming.
### Puzzle
The example problem for our exploration will be a puzzle similar to what you may have seen before.
**How many triangles are there?**
![][7]
### Getting started
Get started by opening a fresh text file with your favorite text editor. Copy all three text blocks in the sections below (Input, Process and Output) together into one file.
#### Input
This section sets up access to the Prolog interface and defines data for the problem. This is a simple case so it is fastest to write the data lines by hand. In larger problems you may get your input data from a file or from a database.
```
#!/usr/bin/python
from pyswip import Prolog
prolog = Prolog()
prolog.assertz("line([a, e, k])")
prolog.assertz("line([a, d, f, j])")
prolog.assertz("line([a, c, g, i])")
prolog.assertz("line([a, b, h])")
prolog.assertz("line([b, c, d, e])")
prolog.assertz("line([e, f, g, h])")
prolog.assertz("line([h, i, j, k])")
```
* The first line is the UNIX way to tell that this text file is a Python program.
Dont forget to make your file executable by using _chmod +x yourfile.py_ .
* The second line imports a Python module which is doing the Python/Prolog bridge.
* The third line makes a Prolog instance available inside Python.
* Next lines are puzzle related. They describe the picture you see above.
Single **small** letters stand for concrete points.
_[a,e,k]_ is the Prolog way to describe a list of three points.
_line()_ declares that it is true that the list inside parentheses is a line .
The idea is to let Python do the work and to feed Prolog.
#### “Process”
This section title is quoted because nothing is actually processed here. This is simply the description (declaration) of the solution.
There is no single variable which gets a new value. Technically the processing is done in the section titled Output below where you find the command _prolog.query()_.
```
prolog.assertz("""
triangle(A, B, C) :-
line(L1),
line(L2),
line(L3),
L1 \= L2,
member(A, L1),
member(B, L1),
member(A, L2),
member(C, L2),
member(B, L3),
member(C, L3),
A @< B,
B @< C""")
```
First of all: All capital letters and strings starting with a capital letter are Prolog variables!
The statements here are the description of what a triangle is and you can read this like:
* **If** all lines after _“:-“_ are true, **then** _triangle(A, B, C)_ is a triangle
* There must exist three lines (L1 to L3).
* Two lines must be different. “\_=_” means not equal in Prolog. We do not want to count a triangle where all three points are on the same line! So we check if at least two different lines are used.
* _member()_ is a Prolog predicate which is true if the first argument is inside the second argument which must be a list. In sum these six lines express that the three points must be pairwise on different lines.
* The last two lines are only true if the three points are in alphabetical order. (“_@&lt;_” compares terms in Prolog.) This is necessary, otherwise [a, h, k] and [a, k, h] would count as two triangles. Also, the case where a triangle contains the same point two or even three times is excluded by these final two lines.
As you can see, it is often not that obvious what defines a triangle. But for a computed approach you must be rather strict and rigorous.
#### Output
After the hard work in the process chapter the rest is easy. Just have Python ask Prolog to search for triangles and count them all.
```
total = 0
for result in prolog.query("triangle(A, B, C)"):
print(result)
total += 1
print("There are", total, "triangles.")
```
Run the program using this command in the directory containing _yourfile.py_ :
```
./yourfile.py
```
The output shows the listing of each triangle found and the final count.
```
{'A': 'a', 'B': 'e', 'C': 'f'}
{'A': 'a', 'B': 'e', 'C': 'g'}
{'A': 'a', 'B': 'e', 'C': 'h'}
{'A': 'a', 'B': 'd', 'C': 'e'}
{'A': 'a', 'B': 'j', 'C': 'k'}
{'A': 'a', 'B': 'f', 'C': 'g'}
{'A': 'a', 'B': 'f', 'C': 'h'}
{'A': 'a', 'B': 'c', 'C': 'e'}
{'A': 'a', 'B': 'i', 'C': 'k'}
{'A': 'a', 'B': 'c', 'C': 'd'}
{'A': 'a', 'B': 'i', 'C': 'j'}
{'A': 'a', 'B': 'g', 'C': 'h'}
{'A': 'a', 'B': 'b', 'C': 'e'}
{'A': 'a', 'B': 'h', 'C': 'k'}
{'A': 'a', 'B': 'b', 'C': 'd'}
{'A': 'a', 'B': 'h', 'C': 'j'}
{'A': 'a', 'B': 'b', 'C': 'c'}
{'A': 'a', 'B': 'h', 'C': 'i'}
{'A': 'd', 'B': 'e', 'C': 'f'}
{'A': 'c', 'B': 'e', 'C': 'g'}
{'A': 'b', 'B': 'e', 'C': 'h'}
{'A': 'e', 'B': 'h', 'C': 'k'}
{'A': 'f', 'B': 'h', 'C': 'j'}
{'A': 'g', 'B': 'h', 'C': 'i'}
There are 24 triangles.
```
There are certainly more elegant ways to display this output but the point is:
**Python should do the output handling for Prolog.**
If you are a star programmer you can make the output look like this:
```
***************************
* There are 24 triangles. *
***************************
```
### Conclusion
Splitting a programming task between Python and Prolog makes it easy to keep the Prolog part pure and monotonic, which is good for logic reasoning. It is also easy to make the input and output handling with Python.
Be aware that Prolog is a bit more complicated and can do much more than what I explained here. You can find a really good and modern introduction here: [The Power of Prolog][4].
--------------------------------------------------------------------------------
via: https://fedoramagazine.org/exploring-the-world-of-declarative-programming/
作者:[pampelmuse][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://fedoramagazine.org/author/pampelmuse/
[b]: https://github.com/lujun9972
[1]: https://fedoramagazine.org/wp-content/uploads/2021/04/explore_declarative-816x345.jpg
[2]: https://unsplash.com/@stefanbc?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText
[3]: https://unsplash.com/s/photos/star-trek?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText
[4]: https://www.metalevel.at/prolog
[5]: https://www.swi-prolog.org/
[6]: https://github.com/yuce/pyswip
[7]: https://fedoramagazine.org/wp-content/uploads/2021/04/triangle2.png

View File

@@ -1,347 +0,0 @@
[#]: subject: (5 ways to process JSON data in Ansible)
[#]: via: (https://opensource.com/article/21/4/process-json-data-ansible)
[#]: author: (Nicolas Leiva https://opensource.com/users/nicolas-leiva)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
5 ways to process JSON data in Ansible
======
Structured data is friendly for automation, and you can take full
advantage of it with Ansible.
![Net catching 1s and 0s or data in the clouds][1]
Exploring and validating data from an environment is a common practice for preventing service disruptions. You can choose to run the process periodically or on-demand, and the data you're checking can come from different sources: telemetry, command outputs, etc.
If the data is _unstructured_, you must do some custom regex magic to retrieve key performance indicators (KPIs) relevant for specific scenarios. If the data is _structured_, you can leverage a wide array of options to make parsing it simpler and more consistent. Structured data conforms to a data model, which allows access to each data field separately. The data for these models is exchanged as key/value pairs and encoded using different formats. JSON, which is widely used in Ansible, is one of them.
There are many resources available in Ansible to work with JSON data, and this article presents five of them. While all these resources are used together in sequence in the examples, it is probably sufficient to use just one or two in most real-life scenarios.
![Magnifying glass looking at 0's and 1's][2]
([Geralt][3], Pixabay License)
The following code snippet is a short JSON document used as input for the examples in this article. If you just want to see the code, it's available in my [GitHub repository][4].
This is sample [pyATS][5] output from a `show ip ospf neighbors` command on a Cisco IOS-XE device:
```
{
   "parsed": {
      "interfaces": {
          "Tunnel0": {
              "neighbors": {
                  "203.0.113.2": {
                      "address": "198.51.100.2",
                      "dead_time": "00:00:39",
                      "priority": 0,
                      "state": "FULL/  -"
                  }
              }
          },
          "Tunnel1": {
              "neighbors": {
                  "203.0.113.2": {
                      "address": "192.0.2.2",
                      "dead_time": "00:00:36",
                      "priority": 0,
                      "state": "INIT/  -"
                  }
              }
          }
      }
   }
}
```
This document lists various interfaces from a networking device describing the Open Shortest Path First ([OSPF][6]) state of any OSPF neighbor present per interface. The goal is to validate that the state of all these OSPF sessions is good (i.e., **FULL**).
This goal is visually simple, but if you have a lot of entries, it wouldn't be. Fortunately, as the following examples demonstrate, you can do this at scale with Ansible.
### 1\. Access a subset of the data
If you are only interested in a specific branch of the data tree, a reference to its path will take you down the JSON structure hierarchy and allow you to select only that portion of the JSON object. The path is made of dot-separated key names.
To begin, create a variable (`input`) in Ansible that reads the JSON-formatted message from a file.
To go two levels down, for example, you need to follow the hierarchy of the key names to that point, which translates to `input.parsed.interfaces`, in this case. `input` is the variable that stores the JSON data, `parsed` the top-level key, and `interfaces` is the subsequent one. In a playbook, this will looks like:
```
\- name: Go down the JSON file 2 levels
  hosts: localhost
  vars:
    input: "{{ lookup('file','output.json') | from_json }}"
  tasks:
   - name: Create interfaces Dictionary
     set_fact:
       interfaces: "{{ input.parsed.interfaces }}"
   - name: Print out interfaces
     debug:
       var: interfaces
```
It gives the following output:
```
TASK [Print out interfaces] *************************************************************************************************************************************
ok: [localhost] =&gt; {
    "msg": {
        "Tunnel0": {
            "neighbors": {
                "203.0.113.2": {
                    "address": "198.51.100.2",
                    "dead_time": "00:00:39",
                    "priority": 0,
                    "state": "FULL/  -"
                }
            }
        },
        "Tunnel1": {
            "neighbors": {
                "203.0.113.2": {
                    "address": "192.0.2.2",
                    "dead_time": "00:00:36",
                    "priority": 0,
                    "state": "INIT/  -"
                }
            }
        }
    }
}
```
The view hasn't changed much; you only trimmed the edges. Baby steps!
### 2\. Flatten out the content
If the previous output doesn't help or you want a better understanding of the data hierarchy, you can produce a more compact output with the `to_paths` filter:
```
\- name: Print out flatten interfaces input
  debug:
    msg: "{{ lookup('ansible.utils.to_paths', interfaces) }}"
```
This will print out as:
```
TASK [Print out flatten interfaces input] ***********************************************************************************************************************
ok: [localhost] =&gt; {
    "msg": {
        "Tunnel0.neighbors['203.0.113.2'].address": "198.51.100.2",
        "Tunnel0.neighbors['203.0.113.2'].dead_time": "00:00:39",
        "Tunnel0.neighbors['203.0.113.2'].priority": 0,
        "Tunnel0.neighbors['203.0.113.2'].state": "FULL/  -",
        "Tunnel1.neighbors['203.0.113.2'].address": "192.0.2.2",
        "Tunnel1.neighbors['203.0.113.2'].dead_time": "00:00:36",
        "Tunnel1.neighbors['203.0.113.2'].priority": 0,
        "Tunnel1.neighbors['203.0.113.2'].state": "INIT/  -"
    }
}
```
### 3\. Use json_query filter (JMESPath)
If you are familiar with a JSON query language such as [JMESPath][7], then Ansible's json_query filter is your friend because it is built upon JMESPath, and you can use the same syntax. If this is new to you, there are plenty of JMESPath examples you can learn from in [JMESPath examples][8]. It is a good resource to have in your toolbox.
Here's how to use it to create a list of the neighbors for all interfaces. The query executed in this is `*.neighbors`:
```
\- name: Create neighbors dictionary (this is now per interface)
  set_fact:
    neighbors: "{{ interfaces | json_query('*.neighbors') }}"
\- name: Print out neighbors
  debug:
    msg: "{{ neighbors }}"
```
Which returns a list you can iterate over:
```
TASK [Print out neighbors] **************************************************************************************************************************************
ok: [localhost] =&gt; {
    "msg": [
        {
            "203.0.113.2": {
                "address": "198.51.100.2",
                "dead_time": "00:00:39",
                "priority": 0,
                "state": "FULL/  -"
            }
        },
        {
            "203.0.113.2": {
                "address": "192.0.2.2",
                "dead_time": "00:00:36",
                "priority": 0,
                "state": "INIT/  -"
            }
        }
    ]
}
```
Other options to query JSON are [jq][9] or [Dq][10] (for pyATS).
### 4\. Access specific data fields
Now you can go through the list of neighbors in a loop to access individual data. This example is interested in the `state` of each one. Based on the field's value, you can trigger an action.
This will generate a message to alert the user if the state of a session isn't **FULL**. Typically, you would notify users through mechanisms like email or a chat message rather than just a log entry, as in this example.
As you loop over the `neighbors` list generated in the previous step, it executes the tasks described in `tasks.yml` to instruct Ansible to print out a **WARNING** message only if the state of the neighbor isn't **FULL** (i.e., `info.value.state is not match("FULL.*")`):
```
\- name: Loop over neighbors
  include_tasks: tasks.yml
  with_items: "{{ neighbors }}"
```
The `tasks.yml` file considers `info` as the dictionary item produced for each neighbor in the list you iterate over:
```
\- name: Print out a WARNING if OSPF state is not FULL
 debug:
   msg: "WARNING: Neighbor {{ info.key }}, with address {{ info.value.address }} is in state {{ info.value.state[0:4]  }}"
 vars:
   info: "{{ lookup('dict', item) }}"
 when: info.value.state is not match("FULL.*")
```
This produces a custom-generated message with different data fields for each neighbor that isn't operational:
```
TASK [Print out a WARNING if OSPF state is not FULL] ************************************************************************************************************
ok: [localhost] =&gt; {
    "msg": "WARNING: Neighbor 203.0.113.2, with address 192.0.2.2 is in state INIT"
}
```
> Note: Filter JSON data in Ansible using [json_query][11].
### 5\. Use a JSON schema to validate your data
A more sophisticated way to validate the data from a JSON message is by using a JSON schema. This gives you more flexibility and a wider array of options to validate different types of data. A schema for this example would need to specify `state` is a `string` that starts with **FULL** if that's the only state you want to be valid (you can access this code in my [GitHub repository][12]):
```
{
 "$schema": "<http://json-schema.org/draft-07/schema\#>",
 "definitions": {
     "neighbor" : {
         "type" : "object",
         "properties" : {
             "address" : {"type" : "string"},
             "dead_time" : {"type" : "string"},
             "priority" : {"type" : "number"},
             "state" : {
                 "type" : "string",
                 "pattern" : "^FULL"
                 }
             },
         "required" : [ "address","state" ]
     }
 },
 "type": "object",
 "patternProperties": {
     ".*" : { "$ref" : "#/definitions/neighbor" }
 }
}
```
As you loop over the neighbors, it reads this schema (`schema.json`) and uses it to validate each neighbor item with the module `validate` and engine `jsonschema`:
```
\- name: Validate state of the neighbor is FULL
  ansible.utils.validate:
    data: "{{ item }}"
    criteria:
     - "{{ lookup('file',  'schema.json') | from_json }}"
    engine: ansible.utils.jsonschema
  ignore_errors: true
  register: result
\- name: Print the neighbor that does not satisfy the desired state
  ansible.builtin.debug:
    msg:
     - "WARNING: Neighbor {{ info.key }}, with address {{ info.value.address }} is in state {{ info.value.state[0:4] }}"
     - "{{ error.data_path }}, found: {{ error.found }}, expected: {{ error.expected }}"
  when: "'errors' in result"
  vars:
    info: "{{ lookup('dict', item) }}"
    error: "{{ result['errors'][0] }}"
```
Save the output of the ones that fail the validation so that you can alert the user with a message:
```
TASK [Validate state of the neighbor is FULL] *******************************************************************************************************************
fatal: [localhost]: FAILED! =&gt; {"changed": false, "errors": [{"data_path": "203.0.113.2.state", "expected": "^FULL", "found": "INIT/  -", "json_path": "$.203.0.113.2.state", "message": "'INIT/  -' does not match '^FULL'", "relative_schema": {"pattern": "^FULL", "type": "string"}, "schema_path": "patternProperties..*.properties.state.pattern", "validator": "pattern"}], "msg": "Validation errors were found.\nAt 'patternProperties..*.properties.state.pattern' 'INIT/  -' does not match '^FULL'. "}
...ignoring
TASK [Print the neighbor that does not satisfy the desired state] ***********************************************************************************************
ok: [localhost] =&gt; {
    "msg": [
        "WARNING: Neighbor 203.0.113.2, with address 192.0.2.2 is in state INIT",
        "203.0.113.2.state, found: INIT/  -, expected: ^FULL"
    ]
}
```
If you'd like a deeper dive:
* You can find a more elaborated example and references in [Using new Ansible utilities for operational state management and remediation][13].
* A good resource to practice JSON schema generation is the [JSON Schema Validator and Generator][14].
* A similar approach is the [Schema Enforcer][15], which lets you create the schema in YAML (helpful if you prefer that syntax).
### Conclusion
Structured data is friendly for automation, and you can take full advantage of it with Ansible. As you determine your KPIs, you can automate checks on them to give you peace of mind in situations such as before and after a maintenance window.
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/4/process-json-data-ansible
作者:[Nicolas Leiva][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/nicolas-leiva
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/data_analytics_cloud.png?itok=eE4uIoaB (Net catching 1s and 0s or data in the clouds)
[2]: https://opensource.com/sites/default/files/uploads/data_pixabay.jpg (Magnifying glass looking at 0's and 1's)
[3]: https://pixabay.com/illustrations/window-hand-magnifying-glass-binary-4354467/
[4]: https://github.com/nleiva/ansible-networking/blob/master/test-json.md#parsing-json-outputs
[5]: https://pypi.org/project/pyats/
[6]: https://en.wikipedia.org/wiki/Open_Shortest_Path_First
[7]: https://jmespath.org/
[8]: https://jmespath.org/examples.html
[9]: https://stedolan.github.io/jq/
[10]: https://pubhub.devnetcloud.com/media/genie-docs/docs/userguide/utils/index.html
[11]: https://blog.networktocode.com/post/ansible-filtering-json-query/
[12]: https://github.com/nleiva/ansible-networking/blob/master/files/schema.json
[13]: https://www.ansible.com/blog/using-new-ansible-utilities-for-operational-state-management-and-remediation
[14]: https://extendsclass.com/json-schema-validator.html
[15]: https://blog.networktocode.com/post/introducing_schema_enforcer/

View File

@@ -1,99 +0,0 @@
[#]: subject: (How to create your first Quarkus application)
[#]: via: (https://opensource.com/article/21/4/quarkus-tutorial)
[#]: author: (Saumya Singh https://opensource.com/users/saumyasingh)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
How to create your first Quarkus application
======
The Quarkus framework is considered the rising star for
Kubernetes-native Java.
![woman on laptop sitting at the window][1]
Programming languages and frameworks continuously evolve to help developers who want to develop and deploy applications with even faster speeds, better performance, and lower footprint. Engineers push themselves to develop the "next big thing" to satisfy developers' demands for faster deployments.
[Quarkus][2] is the latest addition to the Java world and considered the rising star for Kubernetes-native Java. It came into the picture in 2019 to optimize Java and commonly used open source frameworks for cloud-native environments. With the Quarkus framework, you can easily go serverless with Java. This article explains why this open source framework is grabbing lots of attention these days and how to create your first Quarkus app.
## What is Quarkus?
Quarkus reimagines the Java stack to give the performance characteristics and developer experience needed to create efficient, high-speed applications. It is a container-first and cloud-native framework for writing Java apps.
You can use your existing skills to code in new ways with Quarkus. It also helps reduce the technical burden in moving to a Kubernetes-centric environment. High-density deployment platforms like Kubernetes need apps with a faster boot time and lower memory usage. Java is still a popular language for developing software but suffers from its focus on productivity at the cost of RAM and CPU.
In the world of virtualization, serverless, and cloud, many developers find Java is not the best fit for developing cloud-native apps. However, the introduction of Quarkus (also known as "Supersonic and Subatomic Java") helps to resolve these issues.
## What are the benefits of Quarkus?
![Quarkus benefits][3]
(Saumya Singh, [CC BY-SA 4.0][4])
Quarkus improves start-up times, execution costs, and productivity. Its main objective is to reduce applications' startup time and memory footprint while providing "developer joy." It fulfills these objectives with native compilation and hot reload features.
### Runtime benefits
![How Quarkus uses memory][5]
(Saumya Singh, [CC BY-SA 4.0][4])
* Lowers memory footprint
* Reduces RSS memory, using 10% of the memory needed for a traditional cloud-native stack
* Offers very fast startup
* Provides a container-first framework, as it is designed to run in a container + Kubernetes environment.
* Focuses heavily on making things work in Kubernetes
### Development benefits
![Developers love Quarkus][6]
(Saumya Singh, [CC BY-SA 4.0][4])
* Provides very fast, live reload during development and coding
* Uses "best of breed" libraries and standards
* Brings specifications and great support
* Unifies and supports imperative and reactive (non-blocking) styles
## Create a Quarkus application in 10 minutes
Now that you have an idea about why you may want to try Quarkus, I'll show you how to use it.
First, ensure you have the prerequisites for creating a Quarkus application
* An IDE like Eclipse, IntelliJ IDEA, VS Code, or Vim
* JDK 8 or 11+ installed with JAVA_HOME configured correctly
* Apache Maven 3.6.2+
You can create a project with either a Maven command or by using code.quarkus.io.
### Use a Maven command:
One of the easiest ways to create a new Quarkus project is to open a terminal and run the following commands, as outlined in the [getting started guide][7]. 
**Linux and macOS users:**
```
mvn io.quarkus:quarkus-maven-plugin:1.13.2.Final:create \
    -DprojectGroupId=org.acme \
    -DprojectArtifactId=getting-started \
    -DclassName="org.acme.getting.started.GreetingResource" \
    -Dpath="/hello"
cd getting-started
```
**Windows users:**
* If you are using `cmd`, don't use the backward slash (`\`): [code]`mvn io.quarkus:quarkus-maven-plugin:1.13.2.Final:create -DprojectGroupId=org.acme -DprojectArtifactId=getting-started -DclassName="org.acme.getting.started.GreetingResource" -Dpath="/hello"`
```
* If you are using PowerShell, wrap `-D` parameters in double-quotes:
```
`mvn io.quarkus:quarkus-maven-plugin:1.13.2.Final:create "

View File

@@ -1,133 +0,0 @@
[#]: subject: (Access freenode using Matrix clients)
[#]: via: (https://fedoramagazine.org/access-freenode-using-matrix-clients/)
[#]: author: (TheEvilSkeleton https://fedoramagazine.org/author/theevilskeleton/)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
Access freenode using Matrix clients
======
![][1]
Fedora Linux 34 Background with freenode and Matrix logos
Matrix (also written [matrix]) is [an open source project][2] and [a communication protocol][3]. The protocol standard is open and it is free to use or implement. Matrix is being recognized as a modern successor to the older [Internet Relay Chat (IRC)][4] protocol. [Mozilla][5], [KDE][6], [FOSDEM][7] and [GNOME][8] are among several large projects that have started using chat clients and servers that operate over the Matrix protocol. Members of the Fedora project have [discussed][9] whether or not the community should switch to using the Matrix protocol.
The Matrix project has implemented an IRC bridge to enable communication between IRC networks (for example, [freenode][10]) and [Matrix homeservers][11]. This article is a guide on how to register, identify and join freenode channels from a Matrix client via the [Matrix IRC bridge][12].
Check out _[Beginners guide to IRC][13]_ for more information about IRC.
### Preparation
You need to set everything up before you register a nick. A nick is a username.
#### Install a client
Before you use the IRC bridge, you need to install a Matrix client. This guide will use Element. Other [Matrix clients][14] are available.
First, install the Matrix client _Element_ from [Flathub][15] on your PC. Alternatively, browse to [element.io][16] to run the Element client directly in your browser.
Next, click _Create Account_ to register a new account on matrix.org (a homeserver hosted by the Matrix project).
#### Create rooms
For the IRC bridge, you need to create rooms with the required users.
First, click the (plus) button next to _People_ on the left side in Element and type _@appservice-irc:matrix.org_ in the field to create a new room with the user.
Second, create another new room with _@freenode_NickServ:matrix.org_.
### Register a nick at freenode
If you have already registered a nick at freenode, skip the remainder of this section.
Registering a nickname is optional, but strongly recommended. Many freenode channels require a registered nickname to join.
First, open the room with _appservice-irc_ and enter the following:
```
!nick <your_nick>
```
Substitute _&lt;your_nick&gt;_ with the username you want to use. If the nick is already taken, _NickServ_ will send you the following message:
```
This nickname is registered. Please choose a different nickname, or identify via /msg NickServ identify <password>.
```
If you receive the above message, use another nick.
Second, open the room with _NickServ_ and enter the following:
```
REGISTER <your_password> <your_email@example.com>
```
You will receive a verification email from freenode. The email will contain a verification command similar to the following:
```
/msg NickServ VERIFY REGISTER <your_nick> <verification_code>
```
Ignore _/msg NickServ_ at the start of the command. Enter the remainder of the command in the room with _NickServ_. Be quick! You will have 24 hours to verify before the code expires.
### Identify your nick at freenode
If you just registered a new nick using the procedure in the previous section, then you should already be identified. If you are already identified, skip the remainder of this section.
First, open the room with _@appservice-irc:matrix.org_ and enter the following:
```
!nick <your_nick>
```
Next, open the room with _@freenode_NickServ:matrix.org_ and enter the following:
```
IDENTIFY <your_nick> <your_password>
```
### Join a freenode channel
To join a freenode channel, press the (plus) button next to _Rooms_ on the left side in Element and type _#freenode_#&lt;your_channel&gt;:matrix.org_. Substitute _&lt;your_channel&gt;_ with the freenode channel you want to join. For example, to join the _#fedora_ channel, use _#freenode_#fedora:matrix.org_. For a list of Fedora Project IRC channels, see _[Communicating_and_getting_help — IRC_for_interactive_community_support][17]_.
### Further reading
* [Matrix IRC wiki][18]
--------------------------------------------------------------------------------
via: https://fedoramagazine.org/access-freenode-using-matrix-clients/
作者:[TheEvilSkeleton][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://fedoramagazine.org/author/theevilskeleton/
[b]: https://github.com/lujun9972
[1]: https://fedoramagazine.org/wp-content/uploads/2021/04/freenode-matrix-816x345.jpeg
[2]: https://matrix.org/
[3]: https://matrix.org/docs/spec/
[4]: https://en.wikipedia.org/wiki/Internet_Relay_Chat
[5]: https://matrix.org/blog/2019/12/19/welcoming-mozilla-to-matrix/
[6]: https://matrix.org/blog/2019/02/20/welcome-to-matrix-kde/
[7]: https://matrix.org/blog/2021/01/04/taking-fosdem-online-via-matrix
[8]: https://wiki.gnome.org/Initiatives/Matrix
[9]: https://discussion.fedoraproject.org/t/the-future-of-real-time-chat-discussion-for-the-fedora-council/24628
[10]: https://en.wikipedia.org/wiki/Freenode
[11]: https://en.wikipedia.org/wiki/Matrix_(protocol)#Servers
[12]: https://github.com/matrix-org/matrix-appservice-irc
[13]: https://fedoramagazine.org/beginners-guide-irc/
[14]: https://matrix.org/clients/
[15]: https://flathub.org/apps/details/im.riot.Riot
[16]: https://app.element.io/
[17]: https://fedoraproject.org/wiki/Communicating_and_getting_help#IRC_for_interactive_community_support
[18]: https://github.com/matrix-org/matrix-appservice-irc/wiki

View File

@@ -1,44 +0,0 @@
[#]: subject: (Flipping burgers to flipping switches: A tech guy's journey)
[#]: via: (https://opensource.com/article/21/5/open-source-story-burgers)
[#]: author: (Clint Byrum https://opensource.com/users/spamaps)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
Flipping burgers to flipping switches: A tech guy's journey
======
You never know how your first job might influence your career path.
![Multi-colored and directional network computer cables][1]
In my last week of high school in 1996, I quit my job at Carl's Jr. because I thought maybe without school, I'd have time to learn enough skills to get hired at a PC shop or something. I didn't know that I actually had incredibly marketable skills as a Linux sysadmin and C programmer, because I was the only tech person I'd ever known (except the people I chatted with on Undernet's #LinuxHelp channel).
I applied at a local company that had maybe the weirdest tech mission I've experienced: Its entire reason for existing was the general lack of industrial-sized QIC-80 tape-formatting machines. Those 80MB backup tapes (gargantuan at a time when 200MB hard disks were huge) were usually formatted at the factory as they came off the line, or you could buy them already formatted at a significantly higher price.
One of the people who developed that line at 3M noticed that formatting them took an hour—over 90% of their time in manufacturing. The machine developed to speed up formatting was, of course, buggy and years too late.
Being a shrewd businessman, instead of fixing the problem for 3M, he quit his job, bought a bunch of cheap PCs and a giant pile of unformatted tapes, and began paying minimum wage to workers in my hometown of San Marcos, Calif., to stuff them into the PCs and pull them out all day long. Then he sold the formatted tapes at a big markup—but less than what 3M charged for them. It was a success.
By the time I got there in 1996, they'd streamlined things a bit. They had a big degaussing machine, about 400 486 PCs stuffed with specialized floppy controllers so that you could address eight tape drives in one machine, custom software (including hardware multiplexers for data collection), and contracts with all the major tape makers (Exabyte, 3M, etc.). I thought I was coming in to be a PC repair tech, as I had passed the test, which asked me to identify all the parts of a PC.
A few weeks in, the lead engineer noticed I had an electronics book (I was studying electronics at [ITT Tech][2], of all places) and pulled me in to help him debug and build the next feature they had cooked up—a custom printed circuit board (PCB) that lit up LEDs to signal a tape's status: formatting (yellow), error (red), or done (green). I didn't write any code or do anything useful, but he still told me I was wasting my time there and should go out and get a real tech job.
That "real tech job" I got was as a junior sysadmin for a local medical device manufacturer. I helped bridge their HP-UX ERP system to their new parent company's Windows NT printers using Linux and Samba—and I was hooked forever on the power of free and open source software (FOSS). I also did some fun debugging while I was there, which you can [read about][3] on my blog.
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/5/open-source-story-burgers
作者:[Clint Byrum][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/spamaps
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/connections_wires_sysadmin_cable.png?itok=d5WqHmnJ (Multi-colored and directional network computer cables)
[2]: https://en.wikipedia.org/wiki/ITT_Technical_Institute
[3]: https://fewbar.com/2020/04/a-bit-of-analysis/

View File

@@ -1,188 +0,0 @@
[#]: subject: (Why I support systemd's plan to take over the world)
[#]: via: (https://opensource.com/article/21/5/systemd)
[#]: author: (David Both https://opensource.com/users/dboth)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
Why I support systemd's plan to take over the world
======
There is no nefarious plan, just one to bring service management into
the 21st century.
![A rack of servers, blue background][1]
Over the years, I have read many articles and posts about how systemd is trying to replace everything and take over everything in Linux. I agree; it is taking over pretty much everything.
But not really "everything-everything." Just "everything" in that middle ground of services that lies between the kernel and things like the GNU core utilities, graphical user interface desktops, and user applications.
Examining Linux's structure is a way to explore this. The following figure shows the three basic software layers found in the operating system. The bottom is the Linux kernel; the middle layer consists of services that may perform startup tasks, such as launching various other services like Network Time Protocol (NTP), Dynamic Host Configuration Protocol (DHCP), Domain Name System (DNS), secure shell (SSH), device management, login services, gettys, Network Manager, journal and log management, logical volume management, printing, kernel module management, local and remote filesystems, sound and video, display management, swap space, system statistics collection, and much more. There are also tens of thousands of new and powerful applications at the top layer.
![systemd services][2]
systemd and the services it manages with respect to the kernel and application programs, including tools used by the sysadmin. (David Both, [CC BY-SA 4.0][3])
This diagram (as well as sysadmins' collective experience over the last several years) makes it clear that systemd is indeed intended to completely replace the old SystemV init system. But I also know (and explained in the previous articles in this systemd series) that it significantly extends the capabilities of the init system.
It is also important to recognize that, although Linus Torvalds rewrote the Unix kernel as an exercise, he did nothing to change the middle layer of system services. He simply recompiled SystemV init to work with his completely new kernel. SystemV is much older than Linux and has needed a complete change to something totally new for decades.
So the kernel is new and is refreshed frequently through the leadership of Torvalds and the work of thousands of programmers around the planet. All of the programs on the top layer of the image above also contribute.
But until recently, there have been no significant enhancements to the init system and management of system services.
In authoring systemd, [Lennart Poettering][4] has done for system services what Linus Torvalds did for the kernel. Like Torvalds and the Linux kernel, Poettering has become the leader and arbiter of what happens inside this middle system services layer. And I like what I see.
### More data for the admin
The new capabilities of systemd include far more status information about services, whether they're running or not. I like having more information about the services I am trying to monitor. For example, look at the DHCPD service. Were I to use the SystemV command, `service dhcpd status`, I would get a simple message that the service is running or stopped. Using the systemd command, `systemctl status dhcpd`, I get much more useful information.
This data is from the server on my personal network:
```
[root@yorktown ~]# systemctl status dhcpd
● dhcpd.service - DHCPv4 Server Daemon
     Loaded: loaded (/usr/lib/systemd/system/dhcpd.service; enabled; vendor preset: disabled)
     Active: active (running) since Fri 2021-04-09 21:43:41 EDT; 4 days ago
       Docs: man:dhcpd(8)
             man:dhcpd.conf(5)
   Main PID: 1385 (dhcpd)
     Status: "Dispatching packets..."
      Tasks: 1 (limit: 9382)
     Memory: 3.6M
        CPU: 240ms
     CGroup: /system.slice/dhcpd.service
             └─1385 /usr/sbin/dhcpd -f -cf /etc/dhcp/dhcpd.conf -user dhcpd -group dhcpd --no-pid
Apr 14 20:51:01 yorktown.both.org dhcpd[1385]: DHCPREQUEST for 192.168.0.7 from e0:d5:5e:a2🇩🇪a4 via eno1
Apr 14 20:51:01 yorktown.both.org dhcpd[1385]: DHCPACK on 192.168.0.7 to e0:d5:5e:a2🇩🇪a4 via eno1
Apr 14 20:51:14 yorktown.both.org dhcpd[1385]: DHCPREQUEST for 192.168.0.8 from e8:40:f2:3d:0e:a8 via eno1
Apr 14 20:51:14 yorktown.both.org dhcpd[1385]: DHCPACK on 192.168.0.8 to e8:40:f2:3d:0e:a8 via eno1
Apr 14 20:51:14 yorktown.both.org dhcpd[1385]: DHCPREQUEST for 192.168.0.201 from 80:fa:5b:63:37:88 via eno1
Apr 14 20:51:14 yorktown.both.org dhcpd[1385]: DHCPACK on 192.168.0.201 to 80:fa:5b:63:37:88 via eno1
Apr 14 20:51:24 yorktown.both.org dhcpd[1385]: DHCPREQUEST for 192.168.0.6 from e0:69:95:45:c4:cd via eno1
Apr 14 20:51:24 yorktown.both.org dhcpd[1385]: DHCPACK on 192.168.0.6 to e0:69:95:45:c4:cd via eno1
Apr 14 20:52:41 yorktown.both.org dhcpd[1385]: DHCPREQUEST for 192.168.0.5 from 00:1e:4f:df:3a:d7 via eno1
Apr 14 20:52:41 yorktown.both.org dhcpd[1385]: DHCPACK on 192.168.0.5 to 00:1e:4f:df:3a:d7 via eno1
[root@yorktown ~]#
```
Having all this information available in a single command is empowering and simplifies problem determination for me. I get more information right at the start. I not only see that the service is up and running but also some of the most recent log entries.
Here is another example that uses a non-operating-system tool. [BOINC][5], the Berkeley Open Infrastructure Network Computing Client, is used to create ad hoc supercomputers out of millions of home computers around the world that are signed up to participate in the computational stages of many types of scientific studies. I am signed up with the [IBM World Community Grid][6] and participate in studies about COVID-19, mapping cancer markers, rainfall in Africa, and more.
The information from this command gives me a more complete picture of how this service is faring:
```
[root@yorktown ~]# systemctl status boinc-client.service
● boinc-client.service - Berkeley Open Infrastructure Network Computing Client
     Loaded: loaded (/usr/lib/systemd/system/boinc-client.service; enabled; vendor preset: disabled)
     Active: active (running) since Fri 2021-04-09 21:43:41 EDT; 4 days ago
       Docs: man:boinc(1)
   Main PID: 1389 (boinc)
      Tasks: 18 (limit: 9382)
     Memory: 1.1G
        CPU: 1month 1w 2d 3h 42min 47.398s
     CGroup: /system.slice/boinc-client.service
             ├─  1389 /usr/bin/boinc
             ├─712591 ../../projects/www.worldcommunitygrid.org/wcgrid_mcm1_map_7.43_x86_64-pc-linux-gnu -SettingsFile MCM1_0174482_7101.txt -DatabaseFile dataset&gt;
             ├─712614 ../../projects/www.worldcommunitygrid.org/wcgrid_mcm1_map_7.43_x86_64-pc-linux-gnu -SettingsFile MCM1_0174448_7280.txt -DatabaseFile dataset&gt;
             ├─713275 ../../projects/www.worldcommunitygrid.org/wcgrid_opn1_autodock_7.17_x86_64-pc-linux-gnu -jobs OPN1_0040707_05092.job -input OPN1_0040707_050&gt;
             ├─713447 ../../projects/www.worldcommunitygrid.org/wcgrid_mcm1_map_7.43_x86_64-pc-linux-gnu -SettingsFile MCM1_0174448_2270.txt -DatabaseFile dataset&gt;
             ├─713517 ../../projects/www.worldcommunitygrid.org/wcgrid_opn1_autodock_7.17_x86_64-pc-linux-gnu -jobs OPN1_0040871_00826.job -input OPN1_0040871_008&gt;
             ├─713657 ../../projects/www.worldcommunitygrid.org/wcgrid_mcm1_map_7.43_x86_64-pc-linux-gnu -SettingsFile MCM1_0174525_7317.txt -DatabaseFile dataset&gt;
             ├─713672 ../../projects/www.worldcommunitygrid.org/wcgrid_mcm1_map_7.43_x86_64-pc-linux-gnu -SettingsFile MCM1_0174529_1537.txt -DatabaseFile dataset&gt;
             └─714586 ../../projects/www.worldcommunitygrid.org/wcgrid_opn1_autodock_7.17_x86_64-pc-linux-gnu -jobs OPN1_0040864_01640.job -input OPN1_0040864_016&gt;
Apr 14 19:57:16 yorktown.both.org boinc[1389]: 14-Apr-2021 19:57:16 [World Community Grid] Finished upload of OPN1_0040707_05063_0_r181439640_0
Apr 14 20:57:36 yorktown.both.org boinc[1389]: 14-Apr-2021 20:57:36 [World Community Grid] Sending scheduler request: To report completed tasks.
Apr 14 20:57:36 yorktown.both.org boinc[1389]: 14-Apr-2021 20:57:36 [World Community Grid] Reporting 1 completed tasks
Apr 14 20:57:36 yorktown.both.org boinc[1389]: 14-Apr-2021 20:57:36 [World Community Grid] Not requesting tasks: don't need (job cache full)
Apr 14 20:57:38 yorktown.both.org boinc[1389]: 14-Apr-2021 20:57:38 [World Community Grid] Scheduler request completed
Apr 14 20:57:38 yorktown.both.org boinc[1389]: 14-Apr-2021 20:57:38 [World Community Grid] Project requested delay of 121 seconds
Apr 14 21:38:03 yorktown.both.org boinc[1389]: 14-Apr-2021 21:38:03 [World Community Grid] Computation for task MCM1_0174482_7657_1 finished
Apr 14 21:38:03 yorktown.both.org boinc[1389]: 14-Apr-2021 21:38:03 [World Community Grid] Starting task OPN1_0040864_01640_0
Apr 14 21:38:05 yorktown.both.org boinc[1389]: 14-Apr-2021 21:38:05 [World Community Grid] Started upload of MCM1_0174482_7657_1_r1768267288_0
Apr 14 21:38:09 yorktown.both.org boinc[1389]: 14-Apr-2021 21:38:09 [World Community Grid] Finished upload of MCM1_0174482_7657_1_r1768267288_0
[root@yorktown ~]#
```
The key is that the BOINC client runs as a daemon and should be managed by the init system. All software that runs as a daemon should be managed by systemd. In fact, even software that still provides SystemV start scripts is managed by systemd.
### systemd standardizes configuration
One of the problems I have had over the years is that, even though "Linux is Linux," not all distributions store their configuration files in the same places or use the same names or even formats. With the huge numbers of Linux hosts in the world, that lack of standardization is a problem. I have also encountered horrible config files and SystemV startup files created by developers trying to jump on the Linux bandwagon and who have no idea how to create software for Linux—and especially the services that must be included in the Linux startup sequence.
The systemd unit files standardize configuration and enforce a startup methodology and organization that provides a level of safety from poorly written SystemV start scripts. They also provide tools that the sysadmin can use to monitor and manage services.
Lennart Poettering wrote a short blog post describing [standard names and locations][7] for common critical systemd configuration files. This standardization makes the sysadmin's job easier. It also makes it easier to automate administrative tasks in environments with multiple Linux distributions. Developers also benefit from this standardization.
### Sometimes, the pain
Any undertaking as massive as replacing and extending an entire init system will cause some level of pain during the transition. I don't mind learning the new commands and how to create configuration files of various types, such as targets, timers, and so on. It does take some work, but I think the results are well worth the effort.
New configuration files and changes in the subsystems that own and manage them can also seem daunting at first. Not to mention that sometimes new tools such as systemd-resolvd can break the way things have worked for a long time, as I point out in [_Resolve systemd-resolved name-service failures with Ansible_][8].
Tools like scripts and Ansible can mitigate the pain while we wait for changes that resolve the pain.
### Conclusion
As I write in [_Learning to love systemd_][9], I can work with either SystemV or systemd init systems, and I have reasons for liking and disliking each:
> "…the real issue and the root cause of most of the controversy between SystemV and systemd is that there is [no choice][10] on the sysadmin level. The choice of whether to use SystemV or systemd has already been made by the developers, maintainers, and packagers of the various distributions—but with good reason. Scooping out and replacing an init system, by its extreme, invasive nature, has a lot of consequences that would be hard to tackle outside the distribution design process."
Because this wholesale replacement is such a massive undertaking, the developers of systemd have been working in stages for several years and replacing various parts of the init system and services and tools that were not parts of the init system but should have been. Many of systemd's new capabilities are made possible only by its tight integration with the services and tools used to manage modern Linux systems.
Although there has been some pain along the way and there will undoubtedly be more, I think the long-term plan and goals are good ones. The advantages of systemd that I have experienced are quite significant.
There is no nefarious plan to take over the world, just one to bring service management into the 21st century.
### Other resources
There is a great deal of information about systemd available on the internet, but much is terse, obtuse, or even misleading. In addition to the resources mentioned in this article, the following web pages offer more detailed and reliable information about systemd startup. This list has grown since I started this series of articles to reflect the research I have done.
* [5 reasons sysadmins love systemd][11]
* The Fedora Project has a good, practical [guide to systemd][12]. It has pretty much everything you need to know to configure, manage, and maintain a Fedora computer using systemd.
* The Fedora Project also has a good [cheat sheet][13] that cross-references the old SystemV commands to comparable systemd ones.
* The [systemd.unit(5) manual page][14] contains a nice list of unit file sections and their configuration options, along with concise descriptions of each.
* Fedora Magazine has a good description of the [Unit file structure][15] as well as other important information. 
* For detailed technical information about systemd and the reasons for creating it, check out Freedesktop.org's [description of systemd][16]. This page is one of the best I have found because it contains many links to other important and accurate documentation.
* Linux.com's "More systemd fun" offers more advanced systemd [information and tips][17].
There is also a series of deeply technical articles for Linux sysadmins by Lennart Poettering, the designer and primary developer of systemd. He wrote these articles between April 2010 and September 2011, but they are just as relevant now as they were then. Much of everything else good written about systemd and its ecosystem is based on these papers. These links are all available at [FreeDesktop.org][18].
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/5/systemd
作者:[David Both][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/dboth
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/rack_server_sysadmin_cloud_520.png?itok=fGmwhf8I (A rack of servers, blue background)
[2]: https://opensource.com/sites/default/files/uploads/systemd-architecture_0.png (systemd services)
[3]: https://creativecommons.org/licenses/by-sa/4.0/
[4]: https://en.wikipedia.org/wiki/Lennart_Poettering
[5]: https://boinc.berkeley.edu/
[6]: https://www.worldcommunitygrid.org/
[7]: http://0pointer.de/blog/projects/the-new-configuration-files
[8]: https://opensource.com/article/21/4/systemd-resolved
[9]: https://opensource.com/article/20/4/systemd
[10]: http://www.osnews.com/story/28026/Editorial_Thoughts_on_Systemd_and_the_Freedom_to_Choose
[11]: https://opensource.com/article/21/4/sysadmins-love-systemd
[12]: https://docs.fedoraproject.org/en-US/quick-docs/understanding-and-administering-systemd/index.html
[13]: https://fedoraproject.org/wiki/SysVinit_to_Systemd_Cheatsheet
[14]: https://man7.org/linux/man-pages/man5/systemd.unit.5.html
[15]: https://fedoramagazine.org/systemd-getting-a-grip-on-units/
[16]: https://www.freedesktop.org/wiki/Software/systemd/
[17]: https://www.linux.com/training-tutorials/more-systemd-fun-blame-game-and-stopping-services-prejudice/
[18]: http://www.freedesktop.org/wiki/Software/systemd

View File

@@ -1,199 +0,0 @@
[#]: subject: (Resolve DHCPD and HTTPD startup failures with Ansible)
[#]: via: (https://opensource.com/article/21/5/ansible-server-services)
[#]: author: (David Both https://opensource.com/users/dboth)
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
Resolve DHCPD and HTTPD startup failures with Ansible
======
Ancient remnants can create strange problems.
![Someone wearing a hardhat and carrying code ][1]
Last year, I had a problem: HTTPD (the [Apache web server][2]) would not start on a reboot or cold boot. To fix it, I added an override file, `/etc/systemd/system/httpd.service.d/override.conf`. It contained the following statements to delay HTTPD's startup until the network is properly started and online. (If you've read my previous [articles][3], you'll know that I use NetworkManager and systemd, not the old SystemV network service and start scripts).
```
# Trying to delay the startup of httpd so that the network is
# fully up and running so that httpd can bind to the correct
# IP address
#
# By David Both, 2020-04-16
[Unit]
After=network-online.target
Wants=network-online.target
```
This circumvention worked until recently when I not only needed to start HTTPD manually; I also had to start DHCPD manually. The wait for the `network-online.target` was no longer working for some reason.
### The causes and my fix
After more internet searches and some digging around my `/etc` directory, I think I discovered the true culprit: I found an ancient remnant from the SystemV and init days in the `/etc/init.d` directory. There was a copy of the old network startup file that should not have been there. I think this file is left over from when I spent some time using the old network program before I switched over to NetworkManager.
Apparently, systemd did what it is supposed to do. It generated a target file from that SystemV start script on the fly and tried to start the network using both the SystemV start script and systemd target that it created. This caused systemd to try to start HTTPD and DHCPD before the network was ready, and those services timed out and did not start.
I removed the `/etc/init.d/network` script from my server, and now it reboots without me having to start the HTTPD and DHCPD services manually. This is a much better solution because it gets to the root cause and is not simply a circumvention.
But this is still not the best solution. That file is owned by the `network-scripts` package and will be replaced if that package is updated. So, I also removed that package from my server, which ensures that this should not happen again. Can you guess how I discovered this?
After I upgraded to Fedora 34, DHCPD and HTTPD again would not start. After some additional experimentation, I found that the `override.conf` file also needed a couple of lines added. These two new lines force those two services to wait until 60 seconds have passed before starting. That seems to solve the problem again—for now.
The revised `override.conf` file now looks like the following. It not only sleeps for 60 seconds before starting the services, it specifies that it is not supposed to start until after the `network-online.target` starts. The latter part is what seems to be broken, but I figured I might as well do both things since one or the other usually seems to work.
```
# Delay the startup of any network service so that the
# network is fully up and running so that httpd can bind to the correct
# IP address.
#
# By David Both, 2020-04-28
#
################################################################################
#                                                                              #
#  Copyright (C) 2021 David Both                                               #
#  [LinuxGeek46@both.org][4]                                                        #
#                                                                              #
#  This program is free software; you can redistribute it and/or modify        #
#  it under the terms of the GNU General Public License as published by        #
#  the Free Software Foundation; either version 2 of the License, or           #
#  (at your option) any later version.                                         #
#                                                                              #
#  This program is distributed in the hope that it will be useful,             #
#  but WITHOUT ANY WARRANTY; without even the implied warranty of              #
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
#  GNU General Public License for more details.                                #
#                                                                              #
#  You should have received a copy of the GNU General Public License           #
#  along with this program; if not, write to the Free Software                 #
#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA   #
#                                                                              #
################################################################################
[Service]
ExecStartPre=/bin/sleep 60
[Unit]
After=network-online.target
Wants=network-online.target
```
### Making it easier with Ansible
This is the type of problem that lends itself to an easy solution using Ansible. So, I created a relatively simple playbook. It has two plays. The first play removes the `network-scripts` and then the `/etc/init.d/network` script because if the script is there and the package is not, the script wont be removed. At least one of my systems had that circumstance. I run this play against all the hosts whether they are workstations or servers.
The second play runs only against the server and installs the `override.conf` files.
```
################################################################################
#                                 fix-network                                  #
#                                                                              #
# This Ansible playbook removes the network-scripts package and the            #
# /etc/rc.d/init.d/network SystemV start script. The /etc/init.d/network       #
# script which conflicts with NetworkManager and causes some network services  #
# such as DHCPD and HTTPD to fail to start.                                    #
#                                                                              #
# This playbook also installs override files for httpd and dhcpd which causes  #
# them to wait 60 seconds before starting.                                     #
#                                                                              #
# All of these things taken together seem to resolve or circumvent the issues  #
# that seem to stem from multiple causes.                                      #
#                                                                              #
# NOTE: The override file is service neutral and can be used with any service. #
#       I have found that using the systemctl edit command does not work as    #
#       it is supposed to according to the documenation.                       #
#                                                                              #
#                                                                              #
# From the network-scripts package info:                                       #
#                                                                              #
# : This package contains the legacy scripts for activating &amp; deactivating of most
# : network interfaces. It also provides a legacy version of 'network' service.
# :
# : The 'network' service is enabled by default after installation of this package,
# : and if the network-scripts are installed alongside NetworkManager, then the
# : ifup/ifdown commands from network-scripts take precedence over the ones provided
# : by NetworkManager.
# :
# : If user has both network-scripts &amp; NetworkManager installed, and wishes to
# : use ifup/ifdown from NetworkManager primarily, then they has to run command:
# :  $ update-alternatives --config ifup
# :
# : Please note that running the command above will also disable the 'network'
# : service.
#                                                                              #
#                                                                              #
#------------------------------------------------------------------------------#
#                                                                              #
# Change History                                                               #
# 2021/04/26 David Both V01.00 New code.                                       #
# 2021/04/28 David Both V01.10 Revised to also remove network-scripts package. #
#                              Also install an override file to do a 60 second #
#                              timeout before the services start.              #                                                                              #                                                                              #
################################################################################
\---
################################################################################
# Play 1: Remove the /etc/init.d/network file
################################################################################
\- name: Play 1 - Remove the network-scripts legacy package on all hosts
  hosts: all
  tasks:
    - name: Remove the network-scripts package if it exists
      dnf:
        name: network-scripts
        state: absent
    - name: Remove /etc/init.d/network file if it exists but the network-scripts package is not installed
      ansible.builtin.file:
        path: /etc/init.d/network
        state: absent
\- name: Play 2 - Install override files for the server services
  hosts: server
  tasks:
    - name: Install the override file for DHCPD
      copy:
        src: /root/ansible/BasicTools/files/override.conf
        dest: /etc/systemd/system/dhcpd.service.d
        mode: 0644
        owner: root
        group: root
    - name: Install the override file for HTTPD
      copy:
        src: /root/ansible/BasicTools/files/override.conf
        dest: /etc/systemd/system/httpd.service.d
        mode: 0644
        owner: root
        group: root
```
This Ansible play removed that bit of cruft from two other hosts on my network and one host on another network that I support. All the hosts that still had the SystemV network script and the `network-scripts` package have not been reinstalled from scratch for several years; they were all upgraded using `dnf-upgrade`. I never circumvented NetworkManager on my newer hosts, so they don't have this problem.
This playbook also installed the override files for both services. Note that the override file has no reference to the service for which it provides the configuration override. For this reason, it can be used for any service that does not start because the attempt to start them has not allowed the NetworkManager service to finish starting up.
### Final thoughts
Although this problem is related to systemd startup, I cannot blame it on systemd. This is, partly at least, a self-inflicted problem caused when I circumvented systemd. At the time, I thought I was making things easier for myself, but I have spent more time trying to locate the problem caused by my avoidance of NetworkManager than I ever saved because I had to learn it anyway. Yet in reality, this problem has multiple possible causes, all of which are addressed by the Ansible playbook.
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/5/ansible-server-services
作者:[David Both][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/dboth
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/build_structure_tech_program_code_construction.png?itok=nVsiLuag (Someone wearing a hardhat and carrying code )
[2]: https://opensource.com/article/18/2/how-configure-apache-web-server
[3]: https://opensource.com/users/dboth
[4]: mailto:LinuxGeek46@both.org

Some files were not shown because too many files have changed in this diff Show More