mirror of
https://github.com/LCTT/TranslateProject.git
synced 2025-01-01 21:50:13 +08:00
commit
421e3393eb
@ -1,13 +1,15 @@
|
||||
使用 TLS 加密保护 VNC 服务器的简单指南
|
||||
======
|
||||
在本教程中,我们将学习使用 TLS 加密安装 VNC 服务器并保护 VNC 会话。
|
||||
此方法已经在 CentOS 6&7 上测试过了,但是也可以在其他的版本/操作系统上运行(RHEL、Scientific Linux 等)。
|
||||
|
||||
在本教程中,我们将学习安装 VNC 服务器并使用 TLS 加密保护 VNC 会话。
|
||||
|
||||
此方法已经在 CentOS 6&7 上测试过了,但是也可以在其它的版本/操作系统上运行(RHEL、Scientific Linux 等)。
|
||||
|
||||
**(推荐阅读:[保护 SSH 会话终极指南][1])**
|
||||
|
||||
### 安装 VNC 服务器
|
||||
|
||||
在机器上安装 VNC 服务器之前,请确保我们有一个可用的 GUI。如果机器上还没有安装 GUI,我们可以通过执行以下命令来安装:
|
||||
在机器上安装 VNC 服务器之前,请确保我们有一个可用的 GUI(图形用户界面)。如果机器上还没有安装 GUI,我们可以通过执行以下命令来安装:
|
||||
|
||||
```
|
||||
yum groupinstall "GNOME Desktop"
|
||||
@ -38,7 +40,7 @@ yum groupinstall "GNOME Desktop"
|
||||
现在我们需要编辑 VNC 配置文件:
|
||||
|
||||
```
|
||||
**# vim /etc/sysconfig/vncservers**
|
||||
# vim /etc/sysconfig/vncservers
|
||||
```
|
||||
|
||||
并添加下面这几行:
|
||||
@ -63,7 +65,7 @@ VNCSERVERARGS[1]= "-geometry 1024×768″
|
||||
|
||||
#### CentOS 7
|
||||
|
||||
在 CentOS 7 上,/etc/sysconfig/vncservers 已经改为 /lib/systemd/system/vncserver@.service。我们将使用这个配置文件作为参考,所以创建一个文件的副本,
|
||||
在 CentOS 7 上,`/etc/sysconfig/vncservers` 已经改为 `/lib/systemd/system/vncserver@.service`。我们将使用这个配置文件作为参考,所以创建一个文件的副本,
|
||||
|
||||
```
|
||||
# cp /lib/systemd/system/vncserver@.service /etc/systemd/system/vncserver@:1.service
|
||||
@ -85,8 +87,8 @@ PIDFile=/home/vncuser/.vnc/%H%i.pid
|
||||
保存文件并退出。接下来重启服务并在启动时启用它:
|
||||
|
||||
```
|
||||
systemctl restart[[email protected]][2]:1.service
|
||||
systemctl enable[[email protected]][2]:1.service
|
||||
# systemctl restart vncserver@:1.service
|
||||
# systemctl enable vncserver@:1.service
|
||||
```
|
||||
|
||||
现在我们已经设置好了 VNC 服务器,并且可以使用 VNC 服务器的 IP 地址从客户机连接到它。但是,在此之前,我们将使用 TLS 加密保护我们的连接。
|
||||
@ -105,7 +107,9 @@ systemctl enable[[email protected]][2]:1.service
|
||||
|
||||
现在,我们可以使用客户机上的 VNC 浏览器访问服务器,使用以下命令以安全连接启动 vnc 浏览器:
|
||||
|
||||
**# vncviewer -SecurityTypes=VeNCrypt,TLSVnc 192.168.1.45:1**
|
||||
```
|
||||
# vncviewer -SecurityTypes=VeNCrypt,TLSVnc 192.168.1.45:1
|
||||
```
|
||||
|
||||
这里,192.168.1.45 是 VNC 服务器的 IP 地址。
|
||||
|
||||
@ -115,14 +119,13 @@ systemctl enable[[email protected]][2]:1.service
|
||||
|
||||
这篇教程就完了,欢迎随时使用下面的评论栏提交你的建议或疑问。
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: http://linuxtechlab.com/secure-vnc-server-tls-encryption/
|
||||
|
||||
作者:[Shusain][a]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
@ -3,31 +3,33 @@
|
||||
|
||||
![](https://www.ostechnix.com/wp-content/uploads/2017/11/Setup-Japanese-Language-Environment-In-Arch-Linux-720x340.jpg)
|
||||
|
||||
在本教程中,我们将讨论如何在 Arch Linux 中设置日语环境。在其他类 Unix 操作系统中,设置日文布局并不是什么大不了的事情。你可以从设置中轻松选择日文键盘布局。然而,在 Arch Linux 下有点困难,ArchWiki 中没有合适的文档。如果你正在使用 Arch Linux 和/或其衍生产品如 Antergos,Manajaro Linux,请遵循本指南在 Arch Linux 及其衍生系统中使用日语。
|
||||
在本教程中,我们将讨论如何在 Arch Linux 中设置日语环境。在其他类 Unix 操作系统中,设置日文布局并不是什么大不了的事情。你可以从设置中轻松选择日文键盘布局。然而,在 Arch Linux 下有点困难,ArchWiki 中没有合适的文档。如果你正在使用 Arch Linux 和/或其衍生产品如 Antergos、Manajaro Linux,请遵循本指南以在 Arch Linux 及其衍生系统中使用日语。
|
||||
|
||||
### 在Arch Linux中设置日语环境
|
||||
### 在 Arch Linux 中设置日语环境
|
||||
|
||||
首先,为了正确查看日语字符,先安装必要的日语字体:
|
||||
|
||||
首先,为了正确查看日语 ASCII 格式,先安装必要的日语字体:
|
||||
```
|
||||
sudo pacman -S adobe-source-han-sans-jp-fonts otf-ipafont
|
||||
```
|
||||
```
|
||||
pacaur -S ttf-monapo
|
||||
```
|
||||
|
||||
如果你尚未安装 pacaur,请参阅[**此链接**][1]。
|
||||
如果你尚未安装 `pacaur`,请参阅[此链接][1]。
|
||||
|
||||
确保你在 `/etc/locale.gen` 中注释掉了(添加 `#` 注释)下面的行。
|
||||
|
||||
确保你在 **/etc/locale.gen** 中注释掉了(添加 # 注释)下面的行。
|
||||
```
|
||||
#ja_JP.UTF-8
|
||||
```
|
||||
|
||||
然后,安装 **iBus** 和 **ibus-anthy**。对于那些想知道原因的,iBus 是类 Unix 系统的输入法(IM)框架,而 ibus-anthy 是 iBus 的日语输入法。
|
||||
然后,安装 iBus 和 ibus-anthy。对于那些想知道原因的,iBus 是类 Unix 系统的输入法(IM)框架,而 ibus-anthy 是 iBus 的日语输入法。
|
||||
|
||||
```
|
||||
sudo pacman -S ibus ibus-anthy
|
||||
```
|
||||
|
||||
在 **~/.xprofile** 中添加以下几行(如果不存在,创建一个):
|
||||
在 `~/.xprofile` 中添加以下几行(如果不存在,创建一个):
|
||||
|
||||
```
|
||||
# Settings for Japanese input
|
||||
export GTK_IM_MODULE='ibus'
|
||||
@ -38,21 +40,21 @@ export XMODIFIERS=@im='ibus'
|
||||
ibus-daemon -drx
|
||||
```
|
||||
|
||||
~/.xprofile 允许我们在 X 用户会话开始时且在窗口管理器启动之前执行命令。
|
||||
|
||||
`~/.xprofile` 允许我们在 X 用户会话开始时且在窗口管理器启动之前执行命令。
|
||||
|
||||
保存并关闭文件。重启 Arch Linux 系统以使更改生效。
|
||||
|
||||
登录到系统后,右键单击任务栏中的 iBus 图标,然后选择 **Preferences**。如果不存在,请从终端运行以下命令来启动 iBus 并打开偏好设置窗口。
|
||||
登录到系统后,右键单击任务栏中的 iBus 图标,然后选择 “Preferences”。如果不存在,请从终端运行以下命令来启动 iBus 并打开偏好设置窗口。
|
||||
|
||||
```
|
||||
ibus-setup
|
||||
```
|
||||
|
||||
选择 Yes 来启动 iBus。你会看到一个像下面的页面。点击 Ok 关闭它。
|
||||
选择 “Yes” 来启动 iBus。你会看到一个像下面的页面。点击 Ok 关闭它。
|
||||
|
||||
[![][2]][3]
|
||||
|
||||
现在,你将看到 iBus 偏好设置窗口。进入 **Input Method** 选项卡,然后单击 “Add” 按钮。
|
||||
现在,你将看到 iBus 偏好设置窗口。进入 “Input Method” 选项卡,然后单击 “Add” 按钮。
|
||||
|
||||
[![][2]][4]
|
||||
|
||||
@ -60,29 +62,27 @@ ibus-setup
|
||||
|
||||
[![][2]][5]
|
||||
|
||||
然后,选择 “Anthy” 并点击添加。
|
||||
然后,选择 “Anthy” 并点击添加:
|
||||
|
||||
[![][2]][6]
|
||||
|
||||
就是这样了。你现在将在输入法栏看到 “Japanese - Anthy”。
|
||||
就是这样了。你现在将在输入法栏看到 “Japanese - Anthy”:
|
||||
|
||||
[![][2]][7]
|
||||
|
||||
根据你的需求在偏好设置中更改日语输入法的选项(点击 Japanese - Anthy -> Preferences)。
|
||||
根据你的需求在偏好设置中更改日语输入法的选项(点击 “Japanese-Anthy” -> “Preferences”)。
|
||||
|
||||
[![][2]][8]
|
||||
|
||||
你还可以在键盘绑定中编辑默认的快捷键。完成所有更改后,点击应用并确定。就是这样。从任务栏中的 iBus 图标中选择日语,或者按下**SUPER 键+空格键**(LCTT译注:SUPER KEY 通常为 Command/Window KEY)来在日语和英语(或者系统中的其他默认语言)之间切换。你可以从 iBus 首选项窗口更改键盘快捷键。
|
||||
|
||||
现在你知道如何在 Arch Linux 及其衍生版中使用日语了。如果你发现我们的指南很有用,那么请您在社交、专业网络上分享,并支持 OSTechNix。
|
||||
|
||||
你还可以在键盘绑定中编辑默认的快捷键。完成所有更改后,点击应用并确定。就是这样。从任务栏中的 iBus 图标中选择日语,或者按下 `SUPER + 空格键”(LCTT 译注:SUPER 键通常为 `Command` 或 `Window` 键)来在日语和英语(或者系统中的其他默认语言)之间切换。你可以从 iBus 首选项窗口更改键盘快捷键。
|
||||
|
||||
现在你知道如何在 Arch Linux 及其衍生版中使用日语了。如果你发现我们的指南很有用,那么请您在社交、专业网络上分享,并支持我们。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.ostechnix.com/setup-japanese-language-environment-arch-linux/
|
||||
|
||||
作者:[][a]
|
||||
作者:[SK][a]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[Locez](https://github.com/locez)
|
||||
|
||||
@ -91,9 +91,9 @@ via: https://www.ostechnix.com/setup-japanese-language-environment-arch-linux/
|
||||
[a]:https://www.ostechnix.com
|
||||
[1]:https://www.ostechnix.com/install-pacaur-arch-linux/
|
||||
[2]:data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7
|
||||
[3]:http://www.ostechnix.com/wp-content/uploads/2017/11/ibus.png ()
|
||||
[4]:http://www.ostechnix.com/wp-content/uploads/2017/11/iBus-preferences.png ()
|
||||
[5]:http://www.ostechnix.com/wp-content/uploads/2017/11/Choose-Japanese.png ()
|
||||
[6]:http://www.ostechnix.com/wp-content/uploads/2017/11/Japanese-Anthy.png ()
|
||||
[7]:http://www.ostechnix.com/wp-content/uploads/2017/11/iBus-preferences-1.png ()
|
||||
[8]:http://www.ostechnix.com/wp-content/uploads/2017/11/ibus-anthy.png ()
|
||||
[3]:http://www.ostechnix.com/wp-content/uploads/2017/11/ibus.png
|
||||
[4]:http://www.ostechnix.com/wp-content/uploads/2017/11/iBus-preferences.png
|
||||
[5]:http://www.ostechnix.com/wp-content/uploads/2017/11/Choose-Japanese.png
|
||||
[6]:http://www.ostechnix.com/wp-content/uploads/2017/11/Japanese-Anthy.png
|
||||
[7]:http://www.ostechnix.com/wp-content/uploads/2017/11/iBus-preferences-1.png
|
||||
[8]:http://www.ostechnix.com/wp-content/uploads/2017/11/ibus-anthy.png
|
@ -0,0 +1,41 @@
|
||||
Gathering project requirements using the Open Decision Framework
|
||||
======
|
||||
|
||||
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/suitcase_container_bag.png?itok=q40lKCBY)
|
||||
|
||||
It's no secret that clear, concise, and measurable requirements lead to more successful projects. A study about large scale projects by [McKinsey & Company in conjunction with the University of Oxford][1] revealed that "on average, large IT projects run 45 percent over budget and 7 percent over time, while delivering 56 percent less value than predicted." The research also showed that some of the causes for this failure were "fuzzy business objectives, out-of-sync stakeholders, and excessive rework."
|
||||
|
||||
Business analysts often find themselves constructing these requirements through ongoing conversations. To do this, they must engage multiple stakeholders and ensure that engaged participants provide clear business objectives. This leads to less rework and more projects with a higher rate of success.
|
||||
|
||||
And they can do it in an open and inclusive way.
|
||||
|
||||
### A framework for success
|
||||
|
||||
One tool for increasing project success rate is the [Open Decision Framework][2]. The Open Decision Framework is an resource that can help users make more effective decisions in organizations that embrace [open principles][3]. The framework stresses three primary principles: being transparent, being inclusive, and being customer-centric.
|
||||
|
||||
**Transparent**. Many times, developers and product designers assume they know how stakeholders use a particular tool or piece of software. But these assumptions are often incorrect and lead to misconceptions about what stakeholders actually need. Practicing transparency when having discussions with developers and business owners is imperative. Development teams need to see not only the "sunny day" scenario but also the challenges that stakeholders face with certain tools or processes. Ask questions such as: "What steps must be done manually?" and "Is this tool performing as you expect?" This provides a shared understanding of the problem and a common baseline for discussion.
|
||||
|
||||
|
||||
**Inclusive**. It is vitally important for business analysts to look at body language and visual cues when gathering requirements. If someone is sitting with arms crossed or rolling their eyes, then it's a clear indication that they do not feel heard. A BA must encourage open communication by reaching out to those that don't feel heard and giving them the opportunity to be heard. Prior to starting the session, lay down ground rules that make the place safe for all to speak their opinions and to share their thoughts. Listen to the feedback provided and respond politely when feedback is offered. Diverse opinions and collaborative problem solving will bring exciting ideas to the session.
|
||||
|
||||
**Customer-centric**. The first step to being customer-centric is to recognize the customer. Who is benefiting from this change, update, or development? Early in the project, conduct a stakeholder mapping to help determine the key stakeholders, their roles in the project, and the ways they fit into the big picture. Involving the right customers and assuring that their needs are met will lead to more successful requirements being identified, more realistic (real-life) tests being conducted, and, ultimately, a successful delivery.
|
||||
|
||||
When your requirement sessions are transparent, inclusive, and customer-centric, you'll gather better requirements. And when you use the [Open Decision Framework][4] for running those sessions, participants feel more involved and empowered, and they deliver more accurate and complete requirements. In other words:
|
||||
|
||||
**Transparent + Inclusive + Customer-Centric = Better Requirements = Successful Projects**
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/open-organization/18/2/constructing-project-requirements
|
||||
|
||||
作者:[Tracy Buckner][a]
|
||||
译者:[译者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/tracyb
|
||||
[1]:http://calleam.com/WTPF/?page_id=1445
|
||||
[2]:https://opensource.com/open-organization/resources/open-decision-framework
|
||||
[3]:https://opensource.com/open-organization/resources/open-org-definition
|
||||
[4]:https://opensource.com/open-organization/16/6/introducing-open-decision-framework
|
@ -0,0 +1,127 @@
|
||||
Arch Anywhere Is Dead, Long Live Anarchy Linux
|
||||
======
|
||||
|
||||
![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/anarchy_main.jpg?itok=fyBpTjQW)
|
||||
|
||||
Arch Anywhere was a distribution aimed at bringing Arch Linux to the masses. Due to a trademark infringement, Arch Anywhere has been completely rebranded to [Anarchy Linux][1]. And I’m here to say, if you’re looking for a distribution that will enable you to enjoy Arch Linux, a little Anarchy will go a very long way. This distribution is seriously impressive in what it sets out to do and what it achieves. In fact, anyone who previously feared Arch Linux can set those fears aside… because Anarchy Linux makes Arch Linux easy.
|
||||
|
||||
Let’s face it; Arch Linux isn’t for the faint of heart. The installation alone will turn off many a new user (and even some seasoned users). That’s where distributions like Anarchy make for an easy bridge to Arch. With a live ISO that can be tested and then installed, Arch becomes as user-friendly as any other distribution.
|
||||
|
||||
Anarchy Linux goes a little bit further than that, however. Let’s fire it up and see what it does.
|
||||
|
||||
### The installation
|
||||
|
||||
The installation of Anarchy Linux isn’t terribly challenging, but it’s also not quite as simple as for, say, [Ubuntu][2], [Linux Mint][3], or [Elementary OS][4]. Although you can run the installer from within the default graphical desktop environment (Xfce4), it’s still much in the same vein as Arch Linux. In other words, you’re going to have to do a bit of work—all within a text-based installer.
|
||||
|
||||
To start, the very first step of the installer (Figure 1) requires you to update the mirror list, which will likely trip up new users.
|
||||
|
||||
![Updating the mirror][6]
|
||||
|
||||
Figure 1: Updating the mirror list is a necessity for the Anarchy Linux installation.
|
||||
|
||||
[Used with permission][7]
|
||||
|
||||
From the options, select Download & Rank New Mirrors. Tab down to OK and hit Enter on your keyboard. You can then select the nearest mirror (to your location) and be done with it. The next few installation screens are simple (keyboard layout, language, timezone, etc.). The next screen should surprise many an Arch fan. Anarchy Linux includes an auto partition tool. Select Auto Partition Drive (Figure 2), tab down to Ok, and hit Enter on your keyboard.
|
||||
|
||||
![partitioning][9]
|
||||
|
||||
Figure 2: Anarchy makes partitioning easy.
|
||||
|
||||
[Used with permission][7]
|
||||
|
||||
You will then have to select the drive to be used (if you only have one drive this is only a matter of hitting Enter). Once you’ve selected the drive, choose the filesystem type to be used (ext2/3/4, btrfs, jfs, reiserfs, xfs), tab down to OK, and hit Enter. Next you must choose whether you want to create SWAP space. If you select Yes, you’ll then have to define how much SWAP to use. The next window will stop many new users in their tracks. It asks if you want to use GPT (GUID Partition Table). This is different than the traditional MBR (Master Boot Record) partitioning. GPT is a newer standard and works better with UEFI. If you’ll be working with UEFI, go with GPT, otherwise, stick with the old standby, MBR. Finally select to write the changes to the disk, and your installation can continue.
|
||||
|
||||
The next screen that could give new users pause, requires the selection of the desired installation. There are five options:
|
||||
|
||||
* Anarchy-Desktop
|
||||
|
||||
* Anarchy-Desktop-LTS
|
||||
|
||||
* Anarchy-Server
|
||||
|
||||
* Anarchy-Server-LTS
|
||||
|
||||
* Anarchy-Advanced
|
||||
|
||||
|
||||
|
||||
|
||||
If you want long term support, select Anarchy-Desktop-LTS, otherwise click Anarchy-Desktop (the default), and tab down to Ok. Click Enter on your keyboard. After you select the type of installation, you will get to select your desktop. You can select from five options: Budgie, Cinnamon, GNOME, Openbox, and Xfce4.
|
||||
Once you’ve selected your desktop, give the machine a hostname, set the root password, create a user, and enable sudo for the new user (if applicable). The next section that will raise the eyebrows of new users is the software selection window (Figure 3). You must go through the various sections and select which software packages to install. Don’t worry, if you miss something, you can always installed it later.
|
||||
|
||||
|
||||
![software][11]
|
||||
|
||||
Figure 3: Selecting the software you want on your system.
|
||||
|
||||
[Used with permission][7]
|
||||
|
||||
Once you’ve made your software selections, tab to Install (Figure 4), and hit Enter on your keyboard.
|
||||
|
||||
![ready to install][13]
|
||||
|
||||
Figure 4: Everything is ready to install.
|
||||
|
||||
[Used with permission][7]
|
||||
|
||||
Once the installation completes, reboot and enjoy Anarchy.
|
||||
|
||||
### Post install
|
||||
|
||||
I installed two versions of Anarchy—one with Budgie and one with GNOME. Both performed quite well, however you might be surprised to see that the version of GNOME installed is decked out with a dock. In fact, comparing the desktops side-by-side and they do a good job of resembling one another (Figure 5).
|
||||
|
||||
![GNOME and Budgie][15]
|
||||
|
||||
Figure 5: GNOME is on the right, Budgie is on the left.
|
||||
|
||||
[Used with permission][7]
|
||||
|
||||
My guess is that you’ll find all desktop options for Anarchy configured in such a way to offer a similar look and feel. Of course, the second you click on the bottom left “buttons”, you’ll see those similarities immediately disappear (Figure 6).
|
||||
|
||||
![GNOME and Budgie][17]
|
||||
|
||||
Figure 6: The GNOME Dash and the Budgie menu are nothing alike.
|
||||
|
||||
[Used with permission][7]
|
||||
|
||||
Regardless of which desktop you select, you’ll find everything you need to install new applications. Open up your desktop menu of choice and select Packages to search for and install whatever is necessary for you to get your work done.
|
||||
|
||||
### Why use Arch Linux without the “Arch”?
|
||||
|
||||
This is a valid question. The answer is simple, but revealing. Some users may opt for a distribution like [Arch Linux][18] because they want the feeling of “elitism” that comes with using, say, [Gentoo][19], without having to go through that much hassle. With regards to complexity, Arch rests below Gentoo, which means it’s accessible to more users. However, along with that complexity in the platform, comes a certain level of dependability that may not be found in others. So if you’re looking for a Linux distribution with high stability, that’s not quite as challenging as Gentoo or Arch to install, Anarchy might be exactly what you want. In the end, you’ll wind up with an outstanding desktop platform that’s easy to work with (and maintain), based on a very highly regarded distribution of Linux.
|
||||
|
||||
That’s why you might opt for Arch Linux without the Arch.
|
||||
|
||||
Anarchy Linux is one of the finest “user-friendly” takes on Arch Linux I’ve ever had the privilege of using. Without a doubt, if you’re looking for a friendlier version of a rather challenging desktop operating system, you cannot go wrong with Anarchy.
|
||||
|
||||
Learn more about Linux through the free ["Introduction to Linux" ][20]course from The Linux Foundation and edX.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.linux.com/learn/intro-to-linux/2018/2/arch-anywhere-dead-long-live-anarchy-linux
|
||||
|
||||
作者:[Jack Wallen][a]
|
||||
译者:[译者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/users/jlwallen
|
||||
[1]:https://anarchy-linux.org/
|
||||
[2]:https://www.ubuntu.com/
|
||||
[3]:https://linuxmint.com/
|
||||
[4]:https://elementary.io/
|
||||
[6]:https://www.linux.com/sites/lcom/files/styles/rendered_file/public/anarchy_install_1.jpg?itok=WgHRqFTf (Updating the mirror)
|
||||
[7]:https://www.linux.com/licenses/category/used-permission
|
||||
[9]:https://www.linux.com/sites/lcom/files/styles/rendered_file/public/anarchy_install_2.jpg?itok=D7HkR97t (partitioning)
|
||||
[10]:/files/images/anarchyinstall3jpg
|
||||
[11]:https://www.linux.com/sites/lcom/files/styles/rendered_file/public/anarchy_install_3.jpg?itok=5-9E2u0S (software)
|
||||
[12]:/files/images/anarchyinstall4jpg
|
||||
[13]:https://www.linux.com/sites/lcom/files/styles/rendered_file/public/anarchy_install_4.jpg?itok=fuSZqtZS (ready to install)
|
||||
[14]:/files/images/anarchyinstall5jpg
|
||||
[15]:https://www.linux.com/sites/lcom/files/styles/rendered_file/public/anarchy_install_5.jpg?itok=4y9kiC8I (GNOME and Budgie)
|
||||
[16]:/files/images/anarchyinstall6jpg
|
||||
[17]:https://www.linux.com/sites/lcom/files/styles/rendered_file/public/anarchy_install_6.jpg?itok=fJ7Lmdci (GNOME and Budgie)
|
||||
[18]:https://www.archlinux.org/
|
||||
[19]:https://www.gentoo.org/
|
||||
[20]:https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux
|
@ -1,162 +0,0 @@
|
||||
Translating by qhwdw
|
||||
Learn your tools: Navigating your Git History
|
||||
============================================================
|
||||
|
||||
Starting a greenfield application everyday is nearly impossible, especially in your daily job. In fact, most of us are facing (somewhat) legacy codebases on a daily basis, and regaining the context of why some feature, or line of code exists in the codebase is very important. This is where `git`, the distributed version control system, is invaluable. Let’s dive in and see how we can use our `git` history and easily navigate through it.
|
||||
|
||||
### Git history
|
||||
|
||||
First and foremost, what is `git` history? As the name says, it is the commit history of a `git` repo. It contains a bunch of commit messages, with their authors’ name, the commit hash and the date of the commit. The easiest way to see the history of a `git`repo, is the `git log` command.
|
||||
|
||||
Sidenote: For the purpose of this post, we will use Ruby on Rails’ repo, the `master`branch. The reason behind this is because Rails has a very good `git` history, with nice commit messages, references and explanations behind every change. Given the size of the codebase, the age and the number of maintainers, it’s certainly one of the best repositories that I have seen. Of course, I am not saying there are no other repositories built with good `git` practices, but this is one that has caught my eye.
|
||||
|
||||
So back to Rails’ repo. If you run `git log` in the Rails’ repo, you will see something like this:
|
||||
|
||||
```
|
||||
commit 66ebbc4952f6cfb37d719f63036441ef98149418Author: Arthur Neves <foo@bar.com>Date: Fri Jun 3 17:17:38 2016 -0400 Dont re-define class SQLite3Adapter on test We were declaring in a few tests, which depending of the order load will cause an error, as the super class could change. see https://github.com/rails/rails/commit/ac1c4e141b20c1067af2c2703db6e1b463b985da#commitcomment-17731383commit 755f6bf3d3d568bc0af2c636be2f6df16c651eb1Merge: 4e85538 f7b850eAuthor: Eileen M. Uchitelle <foo@bar.com>Date: Fri Jun 3 10:21:49 2016 -0400 Merge pull request #25263 from abhishekjain16/doc_accessor_thread [skip ci] Fix grammarcommit f7b850ec9f6036802339e965c8ce74494f731b4aAuthor: Abhishek Jain <foo@bar.com>Date: Fri Jun 3 16:49:21 2016 +0530 [skip ci] Fix grammarcommit 4e85538dddf47877cacc65cea6c050e349af0405Merge: 082a515 cf2158cAuthor: Vijay Dev <foo@bar.com>Date: Fri Jun 3 14:00:47 2016 +0000 Merge branch 'master' of github.com:rails/docrails Conflicts: guides/source/action_cable_overview.mdcommit 082a5158251c6578714132e5c4f71bd39f462d71Merge: 4bd11d4 3bd30d9Author: Yves Senn <foo@bar.com>Date: Fri Jun 3 11:30:19 2016 +0200 Merge pull request #25243 from sukesan1984/add_i18n_validation_test Add i18n_validation_testcommit 4bd11d46de892676830bca51d3040f29200abbfaMerge: 99d8d45 e98caf8Author: Arthur Nogueira Neves <foo@bar.com>Date: Thu Jun 2 22:55:52 2016 -0400 Merge pull request #25258 from alexcameron89/master [skip ci] Make header bullets consistent in engines.mdcommit e98caf81fef54746126d31076c6d346c48ae8e1bAuthor: Alex Kitchens <foo@bar.com>Date: Thu Jun 2 21:26:53 2016 -0500 [skip ci] Make header bullets consistent in engines.md
|
||||
```
|
||||
|
||||
As you can see, the `git log` shows the commit hash, the author and his email and the date of when the commit was created. Of course, `git` being super customisable, it allows you to customise the output format of the `git log` command. Let’s say, we want to just see the first line of the commit message, we could run `git log --oneline`, which will produce a more compact log:
|
||||
|
||||
```
|
||||
66ebbc4 Dont re-define class SQLite3Adapter on test755f6bf Merge pull request #25263 from abhishekjain16/doc_accessor_threadf7b850e [skip ci] Fix grammar4e85538 Merge branch 'master' of github.com:rails/docrails082a515 Merge pull request #25243 from sukesan1984/add_i18n_validation_test4bd11d4 Merge pull request #25258 from alexcameron89/mastere98caf8 [skip ci] Make header bullets consistent in engines.md99d8d45 Merge pull request #25254 from kamipo/fix_debug_helper_test818397c Merge pull request #25240 from matthewd/reloadable-channels2c5a8ba Don't blank pad day of the month when formatting dates14ff8e7 Fix debug helper test
|
||||
```
|
||||
|
||||
To see all of the `git log` options, I recommend checking out manpage of `git log`, available in your terminal via `man git-log` or `git help log`. A tip: if `git log` is a bit scarse or complicated to use, or maybe you are just bored, I recommend checking out various `git` GUIs and command line tools. In the past I’ve used [GitX][1] which was very good, but since the command line feels like home to me, after trying [tig][2] I’ve never looked back.
|
||||
|
||||
### Finding Nemo
|
||||
|
||||
So now, since we know the bare minimum of the `git log` command, let’s see how we can explore the history more effectively in our everyday work.
|
||||
|
||||
Let’s say, hypothetically, we are suspecting an unexpected behaviour in the`String#classify` method and we want to find how and where it has been implemented.
|
||||
|
||||
One of the first commands that you can use, to see where the method is defined, is `git grep`. Simply said, this command prints out lines that match a certain pattern. Now, to find the definition of the method, it’s pretty simple - we can grep for `def classify` and see what we get:
|
||||
|
||||
```
|
||||
➜ git grep 'def classify'activesupport/lib/active_support/core_ext/string/inflections.rb: def classifyactivesupport/lib/active_support/inflector/methods.rb: def classify(table_name)tools/profile: def classify
|
||||
```
|
||||
|
||||
Now, although we can already see where our method is created, we are not sure on which line it is. If we add the `-n` flag to our `git grep` command, `git` will provide the line numbers of the match:
|
||||
|
||||
```
|
||||
➜ git grep -n 'def classify'activesupport/lib/active_support/core_ext/string/inflections.rb:205: def classifyactivesupport/lib/active_support/inflector/methods.rb:186: def classify(table_name)tools/profile:112: def classify
|
||||
```
|
||||
|
||||
Much better, right? Having the context in mind, we can easily figure out that the method that we are looking for lives in `activesupport/lib/active_support/core_ext/string/inflections.rb`, on line 205\. The `classify` method, in all of it’s glory looks like this:
|
||||
|
||||
```
|
||||
# Creates a class name from a plural table name like Rails does for table names to models.# Note that this returns a string and not a class. (To convert to an actual class# follow +classify+ with +constantize+.)## 'ham_and_eggs'.classify # => "HamAndEgg"# 'posts'.classify # => "Post"def classify ActiveSupport::Inflector.classify(self)end
|
||||
```
|
||||
|
||||
Although the method we found is the one we usually call on `String`s, it invokes another method on the `ActiveSupport::Inflector`, with the same name. Having our `git grep` result available, we can easily navigate there, since we can see the second line of the result being`activesupport/lib/active_support/inflector/methods.rb` on line 186\. The method that we are are looking for is:
|
||||
|
||||
```
|
||||
# Creates a class name from a plural table name like Rails does for table# names to models. Note that this returns a string and not a Class (To# convert to an actual class follow +classify+ with #constantize).## classify('ham_and_eggs') # => "HamAndEgg"# classify('posts') # => "Post"## Singular names are not handled correctly:## classify('calculus') # => "Calculus"def classify(table_name) # strip out any leading schema name camelize(singularize(table_name.to_s.sub(/.*\./, ''.freeze)))end
|
||||
```
|
||||
|
||||
Boom! Given the size of Rails, finding this should not take us more than 30 seconds with the help of `git grep`.
|
||||
|
||||
### So, what changed last?
|
||||
|
||||
Now, since we have the method available, we need to figure out what were the changes that this file has gone through. The since we know the correct file name and line number, we can use `git blame`. This command shows what revision and author last modified each line of a file. Let’s see what were the latest changes made to this file:
|
||||
|
||||
```
|
||||
git blame activesupport/lib/active_support/inflector/methods.rb
|
||||
```
|
||||
|
||||
Whoa! Although we get the last change of every line in the file, we are more interested in the specific method (lines 176 to 189). Let’s add a flag to the `git blame` command, that will show the blame of just those lines. Also, we will add the `-s` (suppress) option to the command, to skip the author names and the timestamp of the revision (commit) that changed the line:
|
||||
|
||||
```
|
||||
git blame -L 176,189 -s activesupport/lib/active_support/inflector/methods.rb9fe8e19a 176) # Creates a class name from a plural table name like Rails does for table5ea3f284 177) # names to models. Note that this returns a string and not a Class (To9fe8e19a 178) # convert to an actual class follow +classify+ with #constantize).51cd6bb8 179) #6d077205 180) # classify('ham_and_eggs') # => "HamAndEgg"9fe8e19a 181) # classify('posts') # => "Post"51cd6bb8 182) #51cd6bb8 183) # Singular names are not handled correctly:5ea3f284 184) #66d6e7be 185) # classify('calculus') # => "Calculus"51cd6bb8 186) def classify(table_name)51cd6bb8 187) # strip out any leading schema name5bb1d4d2 188) camelize(singularize(table_name.to_s.sub(/.*\./, ''.freeze)))51cd6bb8 189) end
|
||||
```
|
||||
|
||||
The output of the `git blame` command now shows all of the file lines and their respective revisions. Now, to see a specific revision, or in other words, what each of those revisions changed, we can use the `git show` command. When supplied a revision hash (like `66d6e7be`) as an argument, it will show you the full revision, with the author name, timestamp and the whole revision in it’s glory. Let’s see what actually changed at the latest revision that changed line 188:
|
||||
|
||||
```
|
||||
git show 5bb1d4d2
|
||||
```
|
||||
|
||||
Whoa! Did you test that? If you didn’t, it’s an awesome [commit][3] by [Schneems][4] that made a very interesting performance optimization by using frozen strings, which makes sense in our current context. But, since we are on this hypothetical debugging session, this doesn’t tell much about our current problem. So, how can we see what changes has our method under investigation gone through?
|
||||
|
||||
### Searching the logs
|
||||
|
||||
Now, we are back to the `git` log. The question is, how can we see all the revisions that the `classify` method went under?
|
||||
|
||||
The `git log` command is quite powerful, because it has a rich list of options to apply to it. We can try to see what the `git` log has stored for this file, using the `-p`options, which means show me the patch for this entry in the `git` log:
|
||||
|
||||
```
|
||||
git log -p activesupport/lib/active_support/inflector/methods.rb
|
||||
```
|
||||
|
||||
This will show us a big list of revisions, for every revision of this file. But, just like before, we are interested in the specific file lines. Let’s modify the command a bit, to show us what we need:
|
||||
|
||||
```
|
||||
git log -L 176,189:activesupport/lib/active_support/inflector/methods.rb
|
||||
```
|
||||
|
||||
The `git log` command accepts the `-L` option, which takes the lines range and the filename as arguments. The format might be a bit weird for you, but it translates to:
|
||||
|
||||
```
|
||||
git log -L <start-line>,<end-line>:<path-to-file>
|
||||
```
|
||||
|
||||
When we run this command, we can see the list of revisions for these lines, which will lead us to the first revision that created the method:
|
||||
|
||||
```
|
||||
commit 51xd6bb829c418c5fbf75de1dfbb177233b1b154Author: Foo Bar <foo@bar.com>Date: Tue Jun 7 19:05:09 2011 -0700 Refactordiff --git a/activesupport/lib/active_support/inflector/methods.rb b/activesupport/lib/active_support/inflector/methods.rb--- a/activesupport/lib/active_support/inflector/methods.rb+++ b/activesupport/lib/active_support/inflector/methods.rb@@ -58,0 +135,14 @@+ # Create a class name from a plural table name like Rails does for table names to models.+ # Note that this returns a string and not a Class. (To convert to an actual class+ # follow +classify+ with +constantize+.)+ #+ # Examples:+ # "egg_and_hams".classify # => "EggAndHam"+ # "posts".classify # => "Post"+ #+ # Singular names are not handled correctly:+ # "business".classify # => "Busines"+ def classify(table_name)+ # strip out any leading schema name+ camelize(singularize(table_name.to_s.sub(/.*\./, '')))+ end
|
||||
```
|
||||
|
||||
Now, look at that - it’s a commit from 2011\. Practically, `git` allows us to travel back in time. This is a very good example of why a proper commit message is paramount to regain context, because from the commit message we cannot really regain context of how this method came to be. But, on the flip side, you should **never ever** get frustrated about it, because you are looking at someone that basically gives away his time and energy for free, doing open source work.
|
||||
|
||||
Coming back from that tangent, we are not sure how the initial implementation of the `classify` method came to be, given that the first commit is just a refactor. Now, if you are thinking something within the lines of “but maybe, just maybe, the method was not on the line range 176 to 189, and we should look more broadly in the file”, you are very correct. The revision that we saw said “Refactor” in it’s commit message, which means that the method was actually there, but after that refactor it started to exist on that line range.
|
||||
|
||||
So, how can we confirm this? Well, believe it or not, `git` comes to the rescue again. The `git log` command accepts the `-S` option, which looks for the code change (additions or deletions) for the specified string as an argument to the command. This means that, if we call `git log -S classify`, we can see all of the commits that changed a line that contains that string.
|
||||
|
||||
If you call this command in the Rails repo, you will first see `git` slowing down a bit. But, when you realise that `git` actually parses all of the revisions in the repo to match the string, it’s actually super fast. Again, the power of `git` at your fingertips. So, to find the first version of the `classify` method, we can run:
|
||||
|
||||
```
|
||||
git log -S 'def classify'
|
||||
```
|
||||
|
||||
This will return all of the revisions where this method has been introduced or changed. If you were following along, the last commit in the log that you will see is:
|
||||
|
||||
```
|
||||
commit db045dbbf60b53dbe013ef25554fd013baf88134Author: David Heinemeier Hansson <foo@bar.com>Date: Wed Nov 24 01:04:44 2004 +0000 Initial git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@4 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
|
||||
```
|
||||
|
||||
How cool is that? It’s the initial commit to Rails, made on a `svn` repo by DHH! This means that `classify` has been around since the beginning of (Rails) time. Now, to see the commit with all of it’s changes, we can run:
|
||||
|
||||
```
|
||||
git show db045dbbf60b53dbe013ef25554fd013baf88134
|
||||
```
|
||||
|
||||
Great, we got to the bottom of it. Now, by using the output from `git log -S 'def classify'` you can track the changes that have happened to this method, combined with the power of the `git log -L` command.
|
||||
|
||||
### Until next time
|
||||
|
||||
Sure, we didn’t really fix any bugs, because we were trying some `git` commands and following along the evolution of the `classify` method. But, nevertheless, `git` is a very powerful tool that we all must learn to use and to embrace. I hope this article gave you a little bit more knowledge of how useful `git` is.
|
||||
|
||||
What are your favourite (or, most effective) ways of navigating through the `git`history?
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
作者简介:
|
||||
|
||||
Backend engineer, interested in Ruby, Go, microservices, building resilient architectures and solving challenges at scale. I coach at Rails Girls in Amsterdam, maintain a list of small gems and often contribute to Open Source.
|
||||
This is where I write about software development, programming languages and everything else that interests me.
|
||||
|
||||
------
|
||||
|
||||
via: https://ieftimov.com/learn-your-tools-navigating-git-history
|
||||
|
||||
作者:[Ilija Eftimov ][a]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://ieftimov.com/
|
||||
[1]:http://gitx.frim.nl/
|
||||
[2]:https://github.com/jonas/tig
|
||||
[3]:https://github.com/rails/rails/commit/5bb1d4d288d019e276335465d0389fd2f5246bfd
|
||||
[4]:https://twitter.com/schneems
|
@ -1,201 +0,0 @@
|
||||
translating by Flowsnow
|
||||
|
||||
Ansible: the Automation Framework That Thinks Like a Sysadmin
|
||||
======
|
||||
|
||||
I've written about and trained folks on various DevOps tools through the years, and although they're awesome, it's obvious that most of them are designed from the mind of a developer. There's nothing wrong with that, because approaching configuration management programmatically is the whole point. Still, it wasn't until I started playing with Ansible that I felt like it was something a sysadmin quickly would appreciate.
|
||||
|
||||
Part of that appreciation comes from the way Ansible communicates with its client computers—namely, via SSH. As sysadmins, you're all very familiar with connecting to computers via SSH, so right from the word "go", you have a better understanding of Ansible than the other alternatives.
|
||||
|
||||
With that in mind, I'm planning to write a few articles exploring how to take advantage of Ansible. It's a great system, but when I was first exposed to it, it wasn't clear how to start. It's not that the learning curve is steep. In fact, if anything, the problem was that I didn't really have that much to learn before starting to use Ansible, and that made it confusing. For example, if you don't have to install an agent program (Ansible doesn't have any software installed on the client computers), how do you start?
|
||||
|
||||
### Getting to the Starting Line
|
||||
|
||||
The reason Ansible was so difficult for me at first is because it's so flexible with how to configure the server/client relationship, I didn't know what I was supposed to do. The truth is that Ansible doesn't really care how you set up the SSH system; it will utilize whatever configuration you have. There are just a couple things to consider:
|
||||
|
||||
1. Ansible needs to connect to the client computer via SSH.
|
||||
|
||||
2. Once connected, Ansible needs to elevate privilege so it can configure the system, install packages and so on.
|
||||
|
||||
Unfortunately, those two considerations really open a can of worms. Connecting to a remote computer and elevating privilege is a scary thing to allow. For some reason, it feels less vulnerable when you simply install an agent on the remote computer and let Chef or Puppet handle privilege escalation. It's not that Ansible is any less secure, but rather, it puts the security decisions in your hands.
|
||||
|
||||
Next I'm going to list a bunch of potential configurations, along with the pros and cons of each. This isn't an exhaustive list, but it should get you thinking along the right lines for what will be ideal in your environment. I also should note that I'm not going to mention systems like Vagrant, because although Vagrant is wonderful for building a quick infrastructure for testing and developing, it's so very different from a bunch of servers that the considerations are too dissimilar really to compare.
|
||||
|
||||
### Some SSH Scenarios
|
||||
|
||||
1) SSHing into remote computer as root with password in Ansible config.
|
||||
|
||||
I started with a terrible idea. The "pros" of this setup is that it eliminates the need for privilege escalation, and there are no other user accounts required on the remote server. But, the cost for such convenience isn't worth it. First, most systems won't let you SSH in as root without changing the default configuration. Those default configurations are there because, quite frankly, it's just a bad idea to allow the root user to connect remotely. Second, putting a root password in a plain-text configuration file on the Ansible machine is mortifying. Really, I mentioned this possibility because it is a possibility, but it's one that should be avoided. Remember, Ansible allows you to configure the connection yourself, and it will let you do really dumb things. Please don't.
|
||||
|
||||
2) SSHing into a remote computer as a regular user, using a password stored in the Ansible config.
|
||||
|
||||
An advantage of this scenario is that it doesn't require much configuration of the clients. Most users are able to SSH in by default, so Ansible should be able to use credentials and log in fine. I personally dislike the idea of a password being stored in plain text in a configuration file, but at least it isn't the root password. If you use this method, be sure to consider how privilege escalation will take place on the remote server. I know I haven't talked about escalating privilege yet, but if you have a password in the config file, that same password likely will be used to gain sudo access. So with one slip, you've compromised not only the remote user's account, but also potentially the entire system.
|
||||
|
||||
3) SSHing into a remote computer as a regular user, authenticating with a key pair that has an empty passphrase.
|
||||
|
||||
This eliminates storing passwords in a configuration file, at least for the logging in part of the process. Key pairs without passphrases aren't ideal, but it's something I often do in an environment like my house. On my internal network, I typically use a key pair without a passphrase to automate many things like cron jobs that require authentication. This isn't the most secure option, because a compromised private key means unrestricted access to the remote user's account, but I like it better than a password in a config file.
|
||||
|
||||
4) SSHing into a remote computer as a regular user, authenticating with a key pair that is secured by a passphrase.
|
||||
|
||||
This is a very secure way of handling remote access, because it requires two different authentication factors: 1) the private key and 2) the passphrase to decrypt it. If you're just running Ansible interactively, this might be the ideal setup. When you run a command, Ansible should prompt you for the private key's passphrase, and then it'll use the key pair to log in to the remote system. Yes, the same could be done by just using a standard password login and not specifying the password in the configuration file, but if you're going to be typing a password on the command line anyway, why not add the layer of protection a key pair offers?
|
||||
|
||||
5) SSHing with a passphrase-protected key pair, but using ssh-agent to "unlock" the private key.
|
||||
|
||||
This doesn't perfectly answer the question of unattended, automated Ansible commands, but it does make a fairly secure setup convenient as well. The ssh-agent program authenticates the passphrase one time and then uses that authentication to make future connections. When I'm using Ansible, this is what I think I'd like to be doing. If I'm completely honest, I still usually use key pairs without passphrases, but that's typically because I'm working on my home servers, not something prone to attack.
|
||||
|
||||
There are some other considerations to keep in mind when configuring your SSH environment. Perhaps you're able to restrict the Ansible user (which is often your local user name) so it can log in only from a specific IP address. Perhaps your Ansible server can live in a different subnet, behind a strong firewall so its private keys are more difficult to access remotely. Maybe the Ansible server doesn't have an SSH server installed on itself so there's no incoming access at all. Again, one of the strengths of Ansible is that it uses the SSH protocol for communication, and it's a protocol you've all had years to tweak into a system that works best in your environment. I'm not a big fan of proclaiming what the "best practice" is, because in reality, the best practice is to consider your environment and choose the setup that fits your situation the best.
|
||||
|
||||
### Privilege Escalation
|
||||
|
||||
Once your Ansible server connects to its clients via SSH, it needs to be able to escalate privilege. If you chose option 1 above, you're already root, and this is a moot point. But since no one chose option 1 (right?), you need to consider how a regular user on the client computer gains access. Ansible supports a wide variety of escalation systems, but in Linux, the most common options are sudo and su. As with SSH, there are a few situations to consider, although there are certainly other options.
|
||||
|
||||
1) Escalate privilege with su.
|
||||
|
||||
For Red Hat/CentOS users, the instinct might be to use su in order to gain system access. By default, those systems configure the root password during install, and to gain privileged access, you need to type it in. The problem with using su is that although it gives you total access to the remote system, it also gives you total access to the remote system. (Yes, that was sarcasm.) Also, the su program doesn't have the ability to authenticate with key pairs, so the password either must be interactively typed or stored in the configuration file. And since it's literally the root password, storing it in the config file should sound like a horrible idea, because it is.
|
||||
|
||||
2) Escalate privilege with sudo.
|
||||
|
||||
This is how Debian/Ubuntu systems are configured. A user in the correct group has access to sudo a command and execute it with root privileges. Out of the box, this still has the problem of password storage or interactive typing. Since storing the user's password in the configuration file seems a little less horrible, I guess this is a step up from using su, but it still gives complete access to a system if the password is compromised. (After all, typing sudo su - will allow users to become root just as if they had the root password.)
|
||||
|
||||
3) Escalate privilege with sudo and configure NOPASSWD in the sudoers file.
|
||||
|
||||
Again, in my local environment, this is what I do. It's not perfect, because it gives unrestricted root access to the user account and doesn't require any passwords. But when I do this, and use SSH key pairs without passphrases, it allows me to automate Ansible commands easily. I'll note again, that although it is convenient, it is not a terribly secure idea.
|
||||
|
||||
4) Escalate privilege with sudo and configure NOPASSWD on specific executables.
|
||||
|
||||
This idea might be the best compromise of security and convenience. Basically, if you know what you plan to do with Ansible, you can give NOPASSWD privilege to the remote user for just those applications it will need to use. It might get a little confusing, since Ansible uses Python for lots of things, but with enough trial and error, you should be able to figure things out. It is more work, but does eliminate some of the glaring security holes.
|
||||
|
||||
### Implementing Your Plan
|
||||
|
||||
Once you decide how you're going to handle Ansible authentication and privilege escalation, you need to set it up. After you become well versed at Ansible, you might be able to use the tool itself to help "bootstrap" new clients, but at first, it's important to configure clients manually so you know what's happening. It's far better to automate a process you're familiar with than to start with automation from the beginning.
|
||||
|
||||
I've written about SSH key pairs in the past, and there are countless articles online for setting it up. The short version, from your Ansible computer, looks something like this:
|
||||
|
||||
```
|
||||
|
||||
# ssh-keygen
|
||||
# ssh-copy-id -i .ssh/id_dsa.pub remoteuser@remote.computer.ip
|
||||
# ssh remoteuser@remote.computer.ip
|
||||
|
||||
```
|
||||
|
||||
If you've chosen to use no passphrase when creating your key pairs, that last step should get you into the remote computer without typing a password or passphrase.
|
||||
|
||||
In order to set up privilege escalation in sudo, you'll need to edit the sudoers file. You shouldn't edit the file directly, but rather use:
|
||||
|
||||
```
|
||||
|
||||
# sudo visudo
|
||||
|
||||
```
|
||||
|
||||
This will open the sudoers file and allow you to make changes safely (it error-checks when you save, so you don't accidentally lock yourself out with a typo). There are examples in the file, so you should be able to figure out how to assign the exact privileges you want.
|
||||
|
||||
Once it's all configured, you should test it manually before bringing Ansible into the picture. Try SSHing to the remote client, and then try escalating privilege using whatever methods you've chosen. Once you have configured the way you'll connect, it's time to install Ansible.
|
||||
|
||||
### Installing Ansible
|
||||
|
||||
Since the Ansible program gets installed only on the single computer, it's not a big chore to get going. Red Hat/Ubuntu systems do package installs a bit differently, but neither is difficult.
|
||||
|
||||
In Red Hat/CentOS, first enable the EPEL repository:
|
||||
|
||||
```
|
||||
|
||||
sudo yum install epel-release
|
||||
|
||||
```
|
||||
|
||||
Then install Ansible:
|
||||
|
||||
```
|
||||
|
||||
sudo yum install ansible
|
||||
|
||||
```
|
||||
|
||||
In Ubuntu, first enable the Ansible PPA:
|
||||
|
||||
```
|
||||
|
||||
sudo apt-add-repository spa:ansible/ansible
|
||||
(press ENTER to access the key and add the repo)
|
||||
|
||||
```
|
||||
|
||||
Then install Ansible:
|
||||
|
||||
```
|
||||
|
||||
sudo apt-get update
|
||||
sudo apt-get install ansible
|
||||
|
||||
```
|
||||
|
||||
### Configuring Ansible Hosts File
|
||||
|
||||
The Ansible system has no way of knowing which clients you want it to control unless you give it a list of computers. That list is very simple, and it looks something like this:
|
||||
|
||||
```
|
||||
|
||||
# file /etc/ansible/hosts
|
||||
|
||||
[webservers]
|
||||
blogserver ansible_host=192.168.1.5
|
||||
wikiserver ansible_host=192.168.1.10
|
||||
|
||||
[dbservers]
|
||||
mysql_1 ansible_host=192.168.1.22
|
||||
pgsql_1 ansible_host=192.168.1.23
|
||||
|
||||
```
|
||||
|
||||
The bracketed sections are specifying groups. Individual hosts can be listed in multiple groups, and Ansible can refer either to individual hosts or groups. This is also the configuration file where things like plain-text passwords would be stored, if that's the sort of setup you've planned. Each line in the configuration file configures a single host, and you can add multiple declarations after the ansible_host statement. Some useful options are:
|
||||
|
||||
```
|
||||
|
||||
ansible_ssh_pass
|
||||
ansible_become
|
||||
ansible_become_method
|
||||
ansible_become_user
|
||||
ansible_become_pass
|
||||
|
||||
```
|
||||
|
||||
### The Ansible Vault
|
||||
|
||||
I also should note that although the setup is more complex, and not something you'll likely do during your first foray into the world of Ansible, the program does offer a way to encrypt passwords in a vault. Once you're familiar with Ansible and you want to put it into production, storing those passwords in an encrypted Ansible vault is ideal. But in the spirit of learning to crawl before you walk, I recommend starting in a non-production environment and using passwordless methods at first.
|
||||
|
||||
### Testing Your System
|
||||
|
||||
Finally, you should test your system to make sure your clients are connecting. The ping test will make sure the Ansible computer can ping each host:
|
||||
|
||||
```
|
||||
|
||||
ansible -m ping all
|
||||
|
||||
```
|
||||
|
||||
After running, you should see a message for each defined host showing a ping: pong if the ping was successful. This doesn't actually test authentication, just the network connectivity. Try this to test your authentication:
|
||||
|
||||
```
|
||||
|
||||
ansible -m shell -a 'uptime' webservers
|
||||
|
||||
```
|
||||
|
||||
You should see the results of the uptime command for each host in the webservers group.
|
||||
|
||||
In a future article, I plan start to dig in to Ansible's ability to manage the remote computers. I'll look at various modules and how you can use the ad-hoc mode to accomplish in a few keystrokes what would take a long time to handle individually on the command line. If you didn't get the results you expected from the sample Ansible commands above, take this time to make sure authentication is working. Check out [the Ansible docs][1] for more help if you get stuck.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: http://www.linuxjournal.com/content/ansible-automation-framework-thinks-sysadmin
|
||||
|
||||
作者:[Shawn Powers][a]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:http://www.linuxjournal.com/users/shawn-powers
|
||||
[1]:http://docs.ansible.com
|
@ -1,418 +0,0 @@
|
||||
translating by heart4lor
|
||||
|
||||
How to Make a Minecraft Server – ThisHosting.Rocks
|
||||
======
|
||||
We’ll show you how to make a Minecraft server with beginner-friendly step-by-step instructions. It will be a persistent multiplayer server that you can play on with your friends from all around the world. You don’t have to be in a LAN.
|
||||
|
||||
### How to Make a Minecraft Server – Quick Guide
|
||||
|
||||
This is our “Table of contents” if you’re in a hurry and want to go straight to the point. We recommend reading everything though.
|
||||
|
||||
* [Learn stuff][1] (optional)
|
||||
|
||||
* [Learn more stuff][2] (optional)
|
||||
|
||||
* [Requirements][3] (required)
|
||||
|
||||
* [Install and start the Minecraft server][4] (required)
|
||||
|
||||
* [Run the server even after you log out of your VPS][5] (optional)
|
||||
|
||||
* [Make the server automatically start at boot][6] (optional)
|
||||
|
||||
* [Configure your Minecraft server][7] (required)
|
||||
|
||||
* [FAQs][8] (optional)
|
||||
|
||||
Before going into the actual instructions, a few things you should know:
|
||||
|
||||
#### Reasons why you would NOT use a specialized Minecraft server hosting provider
|
||||
|
||||
Since you’re here, you’re obviously interested in hosting your own Minecraft server. There are more reasons why you would not use a specialized Minecraft hosting provider, but here are a few:
|
||||
|
||||
* They’re slow most of the time. This is because you actually share the resources with multiple users. It becomes overloaded at some point. Most of them oversell their servers too.
|
||||
|
||||
* You don’t have full control over the Minecraft server or the actual server. You cannot customize anything you want to.
|
||||
|
||||
* You’re limited. Those kinds of hosting plans are always limited in one way or another.
|
||||
|
||||
Of course, there are positives to using a Minecraft hosting provider. The best upside is that you don’t actually have to do all the stuff we’ll write about below. But where’s the fun in that?
|
||||
![🙂](https://s.w.org/images/core/emoji/2.3/svg/1f642.svg)
|
||||
|
||||
#### Why you should NOT use your personal computer to make a Minecraft server
|
||||
|
||||
We noticed lots of tutorials showing you how to host a server on your own computer. There are downsides to doing that, like:
|
||||
|
||||
* Your home internet is not secured enough to handle DDoS attacks. Game servers are often prone to DDoS attacks, and your home network setup is most probably not secured enough to handle them. It’s most likely not powerful enough to handle a small attack.
|
||||
|
||||
* You’ll need to handle port forwarding. If you’ve tried making a Minecraft server on your home network, you’ve surely stumbled upon port forwarding and had issues with it.
|
||||
|
||||
* You’ll need to keep your computer on at all times. Your electricity bill will sky-rocket and you’ll add unnecessary load to your hardware. The hardware most servers use is enterprise-grade and designed to handle loads, with improved stability and longevity.
|
||||
|
||||
* Your home internet is not fast enough. Home networks are not designed to handle multiplayer games. You’ll need a much larger internet plan to even consider making a small server. Luckily, data centers have multiple high-speed, enterprise-grade internet connections making sure they have (or strive to have) 100% uptime.
|
||||
|
||||
* Your hardware is most likely not good enough. Again, servers use enterprise-grade hardware, latest and fastest CPUs, SSDs, and much more. Your personal computer most likely does not.
|
||||
|
||||
* You probably use Windows/MacOS on your personal computer. Though this is debatable, we believe that Linux is much better for game hosting. Don’t worry, you don’t really need to know everything about Linux to make a Minecraft server (though it’s recommended). We’ll show you everything you need to know.
|
||||
|
||||
Our tip is not to use your personal computer, though technically you can. It’s not expensive to buy a cloud server. We’ll show you how to make a Minecraft server on cloud hosting below. It’s easy if you carefully follow the steps.
|
||||
|
||||
### Making a Minecraft Server – Requirements
|
||||
|
||||
There are a few requirements. You should have and know all of this before continuing to the tutorial:
|
||||
|
||||
* You’ll need a [Linux cloud server][9]. We recommend [Vultr][10]. Their prices are cheap, services are high-quality, customer support is great, all server hardware is high-end. Check the [Minecraft server requirements][11] to find out what kind of server you should get (resources like RAM and Disk space). We recommend getting the $20 per month server. They support hourly pricing so if you only need the server temporary for playing with friends, you’ll pay less. Choose the Ubuntu 16.04 distro during signup. Choose the closest server location to where your players live during the signup process. Keep in mind that you’ll be responsible for your server. So you’ll have to secure it and manage it. If you don’t want to do that, you can get a [managed server][12], in which case the hosting provider will likely make a Minecraft server for you.
|
||||
|
||||
* You’ll need an SSH client to connect to the Linux cloud server. [PuTTy][13] is often recommended for beginners, but we also recommend [MobaXTerm][14]. There are many other SSH clients to choose from, so pick your favorite.
|
||||
|
||||
* You’ll need to setup your server (basic security setup at least). Google it and you’ll find many tutorials. You can use [Linode’s Security Guide][15] and follow the exact steps on your [Vultr][16] server.
|
||||
|
||||
* We’ll handle the software requirements like Java below.
|
||||
|
||||
And finally, onto our actual tutorial:
|
||||
|
||||
### How to Make a Minecraft Server on Ubuntu (Linux)
|
||||
|
||||
These instructions are written for and tested on an Ubuntu 16.04 server from [Vultr][17]. Though they’ll also work on Ubuntu 14.04, [Ubuntu 18.04][18], and any other Ubuntu-based distro, and any other server provider.
|
||||
|
||||
We’re using the default Vanilla server from Minecraft. You can use alternatives like CraftBukkit or Spigot that allow more customizations and plugins. Though if you use too many plugins you’ll essentially ruin the server. There are pros and cons to each one. Nevertheless, the instructions below are for the default Vanilla server to keep things simple and beginner-friendly. We may publish a tutorial for CraftBukkit soon if there’s an interest.
|
||||
|
||||
#### 1. Login to your server
|
||||
|
||||
We’ll use the root user. If you use a limited-user, you’ll have to execute most commands with ‘sudo’. You’ll get a warning if you’re doing something you don’t have enough permissions for.
|
||||
|
||||
You can login to your server via your SSH client. Use your server IP and your port (most likely 22).
|
||||
|
||||
After you log in, make sure you [secure your server][19].
|
||||
|
||||
#### 2. Update Ubuntu
|
||||
|
||||
You should always first update your Ubuntu before you do anything else. You can update it with the following commands:
|
||||
|
||||
```
|
||||
apt-get update && apt-get upgrade
|
||||
```
|
||||
|
||||
Hit “enter” and/or “y” when prompted.
|
||||
|
||||
#### 3. Install necessary tools
|
||||
|
||||
You’ll need a few packages and tools for various things in this tutorial like text editing, making your server persistent etc. Install them with the following command:
|
||||
|
||||
```
|
||||
apt-get install nano wget screen bash default-jdk ufw
|
||||
```
|
||||
|
||||
Some of them may already be installed.
|
||||
|
||||
#### 4. Download Minecraft Server
|
||||
|
||||
First, create a directory where you’ll store your Minecraft server and all other files:
|
||||
|
||||
```
|
||||
mkdir /opt/minecraft
|
||||
```
|
||||
|
||||
And navigate to the new directory:
|
||||
|
||||
```
|
||||
cd /opt/minecraft
|
||||
```
|
||||
|
||||
Now you can download the Minecraft Server file. Go to the [download page][20] and get the link there. Download the file with wget:
|
||||
|
||||
```
|
||||
wget https://s3.amazonaws.com/Minecraft.Download/versions/1.12.2/minecraft_server.1.12.2.jar
|
||||
```
|
||||
|
||||
#### 5. Install the Minecraft server
|
||||
|
||||
Once you’ve downloaded the server .jar file, you need to run it once and it will generate some files, including an eula.txt license file. The first time you run it, it will return an error and exit. That’s supposed to happen. Run in with the following command:
|
||||
|
||||
```
|
||||
java -Xms2048M -Xmx3472M -jar minecraft_server.1.12.2.jar nogui
|
||||
```
|
||||
|
||||
“-Xms2048M” is the minimum RAM that your Minecraft server can use and “-Xmx3472M” is the maximum. [Adjust][21] this based on your server’s resources. If you got the 4GB RAM server from [Vultr][22] you can leave them as-is, if you don’t use the server for anything else other than Minecraft.
|
||||
|
||||
After that command ends and returns an error, a new eula.txt file will be generated. You need to accept the license in that file. You can do that by adding “eula=true” to the file with the following command:
|
||||
|
||||
```
|
||||
sed -i.orig 's/eula=false/eula=true/g' eula.txt
|
||||
```
|
||||
|
||||
You can now start the server again and access the Minecraft server console with that same java command from before:
|
||||
|
||||
```
|
||||
java -Xms2048M -Xmx3472M -jar minecraft_server.1.12.2.jar nogui
|
||||
```
|
||||
|
||||
Make sure you’re in the /opt/minecraft directory, or the directory where you installed your MC server.
|
||||
|
||||
You’re free to stop here if you’re just testing this and need it for the short-term. If you’re having trouble loggin into the server, you’ll need to [configure your firewall][23].
|
||||
|
||||
The first time you successfully start the server it will take a bit longer to generate
|
||||
|
||||
We’ll show you how to create a script so you can start the server with it.
|
||||
|
||||
#### 6. Start the Minecraft server with a script, make it persistent, and enable it at boot
|
||||
|
||||
To make things easier, we’ll create a bash script that will start the server automatically.
|
||||
|
||||
So first, create a bash script with nano:
|
||||
|
||||
```
|
||||
nano /opt/minecraft/startminecraft.sh
|
||||
```
|
||||
|
||||
A new (blank) file will open. Paste the following:
|
||||
|
||||
```
|
||||
#!/bin/bash
|
||||
cd /opt/minecraft/ && java -Xms2048M -Xmx3472M -jar minecraft_server.1.12.2.jar nogui
|
||||
```
|
||||
|
||||
If you’re new to nano – you can save and close the file with “CTRL + X”, then “Y”, and hitting enter. This script navigates to your Minecraft server directory you created previously and runs the java command for starting the server. You need to make it executable with the following command:
|
||||
|
||||
```
|
||||
chmod +x startminecraft.sh
|
||||
```
|
||||
|
||||
Then, you can start the server anytime with the following command:
|
||||
|
||||
```
|
||||
/opt/minecraft/startminecraft.sh
|
||||
```
|
||||
|
||||
But, if/when you log out of the SSH session the server will turn off. To keep the server up without being logged in all the time, you can use a screen session. A screen session basically means that it will keep running until the actual server reboots or turns off.
|
||||
|
||||
Start a screen session with this command:
|
||||
|
||||
```
|
||||
screen -S minecraft
|
||||
```
|
||||
|
||||
Once you’re in the screen session (looks like you would start a new ssh session), you can use the bash script from earlier to start the server:
|
||||
|
||||
```
|
||||
/opt/minecraft/startminecraft.sh
|
||||
```
|
||||
|
||||
To get out of the screen session, you should press CTRL + A-D. Even after you get out of the screen session (detach), the server will keep running. You can safely log off your Ubuntu server now, and the Minecraft server you created will keep running.
|
||||
|
||||
But, if the Ubuntu server reboots or shuts off, the screen session won’t work anymore. So **to do everything we did before automatically at boot** , do the following:
|
||||
|
||||
Open the /etc/rc.local file:
|
||||
|
||||
```
|
||||
nano /etc/rc.local
|
||||
```
|
||||
|
||||
and add the following line above the “exit 0” line:
|
||||
|
||||
```
|
||||
screen -dm -S minecraft /opt/minecraft/startminecraft.sh
|
||||
exit 0
|
||||
```
|
||||
|
||||
Save and close the file.
|
||||
|
||||
To access the Minecraft server console, just run the following command to attach to the screen session:
|
||||
|
||||
```
|
||||
screen -r minecraft
|
||||
```
|
||||
|
||||
That’s it for now. Congrats and have fun! You can now connect to your Minecraft server or configure/modify it.
|
||||
|
||||
### Configure your Ubuntu Server
|
||||
|
||||
You’ll, of course, need to set up your Ubuntu server and secure it if you haven’t already done so. Follow the [guide we mentioned earlier][24] and google it for more info. The configurations you need to do for your Minecraft server on your Ubuntu server are:
|
||||
|
||||
#### Enable and configure the firewall
|
||||
|
||||
First, if it’s not already enabled, you should enable UFW that you previously installed:
|
||||
|
||||
```
|
||||
ufw enable
|
||||
```
|
||||
|
||||
You should allow the default Minecraft server port:
|
||||
|
||||
```
|
||||
ufw allow 25565/tcp
|
||||
```
|
||||
|
||||
You should allow and deny other rules depending on how you use your server. You should deny ports like 80 and 443 if you don’t use the server for hosting websites. Google a UFW/Firewall guide for Ubuntu and you’ll get recommendations. Be careful when setting up your firewall, you may lock yourself out of your server if you block the SSH port.
|
||||
|
||||
Since this is the default port, it often gets automatically scanned and attacked. You can prevent attacks by blocking access to anyone that’s not of your whitelist.
|
||||
|
||||
First, you need to enable the whitelist mode in your [server.properties][25] file. To do that, open the file:
|
||||
|
||||
```
|
||||
nano /opt/minecraft/server.properties
|
||||
```
|
||||
|
||||
And change “white-list” line to “true”:
|
||||
|
||||
```
|
||||
white-list=true
|
||||
```
|
||||
|
||||
Save and close the file.
|
||||
|
||||
Then restart your server (either by restarting your Ubuntu server or by running the start bash script again):
|
||||
|
||||
```
|
||||
/opt/minecraft/startminecraft.sh
|
||||
```
|
||||
|
||||
Access the Minecraft server console:
|
||||
|
||||
```
|
||||
screen -r minecraft
|
||||
```
|
||||
|
||||
And if you want someone to be able to join your server, you need to add them to the whitelist with the following command:
|
||||
|
||||
```
|
||||
whitelist add PlayerUsername
|
||||
```
|
||||
|
||||
To remove them from the whitelist, use:
|
||||
|
||||
```
|
||||
whitelist remove PlayerUsername
|
||||
```
|
||||
|
||||
Exit the screen session (server console) with CTRL + A-D. It’s worth noting that this will deny access to everyone but the whitelisted usernames.
|
||||
|
||||
[![how to create a minecraft server](https://thishosting.rocks/wp-content/uploads/2018/01/create-a-minecraft-server.jpg)][26]
|
||||
|
||||
### How to Make a Minecraft Server – FAQs
|
||||
|
||||
We’ll answer some frequently asked questions about Minecraft Servers and our guide.
|
||||
|
||||
#### How do I restart the Minecraft server?
|
||||
|
||||
If you followed every step from our tutorial, including enabling the server to start on boot, you can just reboot your Ubuntu server. If you didn’t set it up to start at boot, you can just run the start script again which will restart the Minecraft server:
|
||||
|
||||
```
|
||||
/opt/minecraft/startminecraft.sh
|
||||
```
|
||||
|
||||
#### How do I configure my Minecraft server?
|
||||
|
||||
You can configure your server using the [server.properties][27] file. Check the Minecraft Wiki for more info, though you can leave everything as-is and it will work perfectly fine.
|
||||
|
||||
If you want to change the game mode, difficulty and stuff like that, you can use the server console. Access the server console by running:
|
||||
|
||||
```
|
||||
screen -r minecraft
|
||||
```
|
||||
|
||||
And execute [commands][28] there. Commands like:
|
||||
|
||||
```
|
||||
difficulty hard
|
||||
```
|
||||
|
||||
```
|
||||
gamemode survival @a
|
||||
```
|
||||
|
||||
You may need to restart the server depending on what command you used. There are many more commands you can use, check the [wiki][29] for more.
|
||||
|
||||
#### How do I upgrade my Minecraft server?
|
||||
|
||||
If there’s a new release, you need to do this:
|
||||
|
||||
Navigate to the minecraft directory:
|
||||
|
||||
```
|
||||
cd /opt/minecraft
|
||||
```
|
||||
|
||||
Download the latest version, example 1.12.3 with wget:
|
||||
|
||||
```
|
||||
wget https://s3.amazonaws.com/Minecraft.Download/versions/1.12.3/minecraft_server.1.12.3.jar
|
||||
```
|
||||
|
||||
Next, run and build the new server:
|
||||
|
||||
```
|
||||
java -Xms2048M -Xmx3472M -jar minecraft_server.1.12.3.jar nogui
|
||||
```
|
||||
|
||||
Finally, update your start script:
|
||||
|
||||
```
|
||||
nano /opt/minecraft/startminecraft.sh
|
||||
```
|
||||
|
||||
And update the version number accordingly:
|
||||
|
||||
```
|
||||
#!/bin/bash
|
||||
cd /opt/minecraft/ && java -Xms2048M -Xmx3472M -jar minecraft_server.1.12.3.jar nogui
|
||||
```
|
||||
|
||||
Now you can restart the server and everything should go well.
|
||||
|
||||
#### Why is your Minecraft server tutorial so long, and yet others are only 2 lines long?!
|
||||
|
||||
We tried to make this beginner-friendly and be as detailed as possible. We also showed you how to make the Minecraft server persistent and start it automatically at boot, we showed you how to configure your server and everything. I mean, sure, you can start a Minecraft server with a couple of lines, but it would definitely suck, for more than one reason.
|
||||
|
||||
#### I don’t know Linux or anything you wrote about here, how do I make a Minecraft server?
|
||||
|
||||
Just read all of our article and copy and paste the commands. If you really don’t know how to do it all, [we can do it for you][30], or just get a [managed][31] server [provider][32] and let them do it for you.
|
||||
|
||||
#### How do I install mods on my server? How do I install plugins?
|
||||
|
||||
Our article is intended to be a starting guide. You should check the [Minecraft wiki][33] for more info, or just google it. There are plenty of tutorials online
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://thishosting.rocks/how-to-make-a-minecraft-server/
|
||||
|
||||
作者:[ThisHosting.Rocks][a]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://thishosting.rocks
|
||||
[1]:https://thishosting.rocks/how-to-make-a-minecraft-server/#reasons
|
||||
[2]:https://thishosting.rocks/how-to-make-a-minecraft-server/#not-pc
|
||||
[3]:https://thishosting.rocks/how-to-make-a-minecraft-server/#requirements
|
||||
[4]:https://thishosting.rocks/how-to-make-a-minecraft-server/#make-minecraft-server
|
||||
[5]:https://thishosting.rocks/how-to-make-a-minecraft-server/#persistent
|
||||
[6]:https://thishosting.rocks/how-to-make-a-minecraft-server/#boot
|
||||
[7]:https://thishosting.rocks/how-to-make-a-minecraft-server/#configure-minecraft-server
|
||||
[8]:https://thishosting.rocks/how-to-make-a-minecraft-server/#faqs
|
||||
[9]:https://thishosting.rocks/cheap-cloud-hosting-providers-comparison/
|
||||
[10]:https://thishosting.rocks/go/vultr/
|
||||
[11]:https://minecraft.gamepedia.com/Server/Requirements/Dedicated
|
||||
[12]:https://thishosting.rocks/best-cheap-managed-vps/
|
||||
[13]:https://www.chiark.greenend.org.uk/~sgtatham/putty/
|
||||
[14]:https://mobaxterm.mobatek.net/
|
||||
[15]:https://www.linode.com/docs/security/securing-your-server/
|
||||
[16]:https://thishosting.rocks/go/vultr/
|
||||
[17]:https://thishosting.rocks/go/vultr/
|
||||
[18]:https://thishosting.rocks/ubuntu-18-04-new-features-release-date/
|
||||
[19]:https://www.linode.com/docs/security/securing-your-server/
|
||||
[20]:https://minecraft.net/en-us/download/server
|
||||
[21]:https://minecraft.gamepedia.com/Commands
|
||||
[22]:https://thishosting.rocks/go/vultr/
|
||||
[23]:https://thishosting.rocks/how-to-make-a-minecraft-server/#configure-minecraft-server
|
||||
[24]:https://www.linode.com/docs/security/securing-your-server/
|
||||
[25]:https://minecraft.gamepedia.com/Server.properties
|
||||
[26]:https://thishosting.rocks/wp-content/uploads/2018/01/create-a-minecraft-server.jpg
|
||||
[27]:https://minecraft.gamepedia.com/Server.properties
|
||||
[28]:https://minecraft.gamepedia.com/Commands
|
||||
[29]:https://minecraft.gamepedia.com/Commands
|
||||
[30]:https://thishosting.rocks/support/
|
||||
[31]:https://thishosting.rocks/best-cheap-managed-vps/
|
||||
[32]:https://thishosting.rocks/best-cheap-managed-vps/
|
||||
[33]:https://minecraft.gamepedia.com/Minecraft_Wiki
|
@ -0,0 +1,176 @@
|
||||
Managing network connections using IFCONFIG & NMCLI commands
|
||||
======
|
||||
Earlier we have discussed how we can configure network connections using three different methods i.e. by editing network interface file, by using GUI & by using nmtui command ([ **READ ARTICLE HERE**][1]). In this tutorial, we are going to use two other methods to configure network connections on our RHEL/CentOS machines.
|
||||
First utility that we will be using is ‘ifconfig’ & we can configure network on almost any Linux distribution using this method.
|
||||
|
||||
### Using Ifconfig
|
||||
|
||||
#### View current network settings
|
||||
|
||||
To view network settings for all the active network interfaces, run
|
||||
|
||||
```
|
||||
$ ifconfig
|
||||
```
|
||||
|
||||
To view network settings all active, inactive interfaces, run
|
||||
|
||||
```
|
||||
$ ifconfig -a
|
||||
```
|
||||
|
||||
|
||||
Or to view network settings for a particular interface, run
|
||||
|
||||
```
|
||||
$ ifconfig enOs3
|
||||
```
|
||||
|
||||
#### Assigning IP address to an interface
|
||||
|
||||
To assign network information on an interface i.e. IP address, netmask & broadcast address, syntax is
|
||||
ifconfig enOs3 IP_ADDRESS netmask SUBNET broadcast BROADCAST_ADDRESS
|
||||
here, we need to pass information as per our network configurations. An example would be
|
||||
|
||||
```
|
||||
$ ifconfig enOs3 192.168.1.100 netmask 255.255.255.0 broadcast 192.168.1.255
|
||||
```
|
||||
|
||||
|
||||
This will assign IP 192.168.1.100 on our network interface enOs3. We can also just modify IP or subnet or broadcast address by running the above command with only that parameter like,
|
||||
|
||||
```
|
||||
$ ifconfig enOs3 192.168.1.100
|
||||
$ ifconfig enOs3 netmask 255.255.255.0
|
||||
$ ifconfig enOs3 broadcast 192.168.1.255
|
||||
```
|
||||
|
||||
|
||||
#### Enabling or disabling a network interface
|
||||
|
||||
To enable a network interface, run
|
||||
|
||||
```
|
||||
$ ifconfig enOs3 up
|
||||
```
|
||||
|
||||
|
||||
To disable a network interface, run
|
||||
|
||||
```
|
||||
$ ifconfig enOs3 down
|
||||
```
|
||||
|
||||
|
||||
( **Recommended read** :- [**Assigning multiple IP addresses to a single NIC**][2])
|
||||
|
||||
**Note:-** When using ifconfig , entries for the gateway address are to be made in /etc/network file or use the following ‘route’ command to add a default gateway,
|
||||
|
||||
```
|
||||
$ route add default gw 192.168.1.1 enOs3
|
||||
```
|
||||
|
||||
|
||||
For adding DNS, make an entry in /etc/resolv.conf.
|
||||
|
||||
### Using NMCLI
|
||||
|
||||
NetworkManager is used as default networking service on RHEL/CentOS 7 versions. It is a very powerful & useful utility for configuring and maintaining network connections. & to control the NetworkManager daemon we can use ‘nmcli’.
|
||||
|
||||
**Syntax** for using nmcli is,
|
||||
```
|
||||
$ nmcli [ OPTIONS ] OBJECT { COMMAND | help }
|
||||
```
|
||||
|
||||
#### Viewing current network settings
|
||||
|
||||
To display the status of NetworkManager, run
|
||||
|
||||
```
|
||||
$ nmcli general status
|
||||
```
|
||||
|
||||
|
||||
to display only the active connections,
|
||||
|
||||
```
|
||||
$ nmcli connection show -a
|
||||
```
|
||||
|
||||
|
||||
to display all active and inactive connections, run
|
||||
|
||||
```
|
||||
$ nmcli connection show
|
||||
```
|
||||
|
||||
|
||||
to display a list of devices recognized by NetworkManager and their current status, run
|
||||
|
||||
```
|
||||
$ nmcli device status
|
||||
```
|
||||
|
||||
|
||||
#### Assigning IP address to an interface
|
||||
|
||||
To assign IP address & default gateway to a network interface, syntax for command is as follows,
|
||||
|
||||
```
|
||||
$ nmcli connection add type ethernet con-name CONNECTION_name ifname INTERFACE_name ip4 IP_address gw4 GATEWAY_address
|
||||
```
|
||||
|
||||
|
||||
Change the fields as per you network information, an example would be
|
||||
|
||||
```
|
||||
$ nmcli connection add type ethernet con-name office ifname enOs3 ip4 192.168.1.100 gw4 192.168.1.1
|
||||
```
|
||||
|
||||
|
||||
Unlike ifconfig command , we can set up a DNS address using nmcli command. To assign a DNS server to an interface, run
|
||||
|
||||
```
|
||||
$ nmcli connection modify office ipv4.dns “8.8.8.8”
|
||||
```
|
||||
|
||||
|
||||
Lastly, we will bring up the newly added connection,
|
||||
|
||||
```
|
||||
$ nmcli connection up office ifname enOs3
|
||||
```
|
||||
|
||||
|
||||
#### Enabling or disabling a network interface
|
||||
|
||||
For enabling an interface using nnmcli, run
|
||||
|
||||
```
|
||||
$ nmcli device connect enOs3
|
||||
```
|
||||
|
||||
|
||||
To disable an interface, run
|
||||
|
||||
```
|
||||
$ nmcli device disconnect enOs3
|
||||
```
|
||||
|
||||
|
||||
That’s it guys. There are many other uses for both of these commands but examples mentioned here should get you started. If having any issues/queries, please mention them in the comment box down below.
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: http://linuxtechlab.com/managing-network-using-ifconfig-nmcli-commands/
|
||||
|
||||
作者:[SHUSAIN][a]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:http://linuxtechlab.com/author/shsuain/
|
||||
[1]:http://linuxtechlab.com/configuring-ip-address-rhel-centos/
|
||||
[2]:http://linuxtechlab.com/ip-aliasing-multiple-ip-single-nic/
|
@ -0,0 +1,39 @@
|
||||
3 Ways to Extend the Power of Kubernetes
|
||||
======
|
||||
|
||||
![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/chen-goldberg-kubecon.png?itok=WR_4i31u)
|
||||
|
||||
The ability to extend Kubernetes is its secret superpower, said Chen Goldberg, Director of Engineering at Google, speaking at the recent [KubeCon + CloudNativeCon][1] in Austin.
|
||||
|
||||
In the race to build tools that help engineers become more productive, Goldberg talked about how she once led a team that developed a platform that did just that. Despite the fact the platform initially worked, it was not extensible, and it was also difficult to modify.
|
||||
|
||||
Fortunately, said Goldberg, Kubernetes suffers from neither of these problems. To begin with, Kubernetes is self-healing system, as it uses controllers that implement what is called a " _Reconciliation Loop._ " In a reconciliation loop, a controller observes the current state of the system and compares it to its desired state. Once it has established the difference between each of these two states, it works towards achieving the desired state. This makes Kubernetes well-adapted to dynamic environments.
|
||||
|
||||
### 3 Ways to Extend Kubernetes
|
||||
|
||||
Goldberg then explained that to build the controllers, you need resources, that is, you need to extend Kubernetes. There are three ways to do that and, from the most flexible (but also more difficult) to the easiest they are: using a Kube aggregator, using an API server builder, or creating a Custom Resource Definition (or CRD).
|
||||
|
||||
The latter allows to extend Kubernetes' functionality even with minimal coding. To demonstrate how it is done, Goggle Software Engineer Anthony Yeh came on stage and showcased adding a stateful set to Kubernetes. (Stateful sets objects used to manage stateful applications, that is applications that need to store the state of the application, keeping track of, for example, a user's identity and their personal settings.) Using _catset_ , a CRD implemented in 100 lines of JavaScript in one single file, Yeh showed how you can add a stateful set to a Kubernetes deployment. A prior extension that was not a CRD, required 24 files and over 3,000 lines of code.
|
||||
|
||||
Addressing the issue of reliability of CRDs, Goldberg said Kubernetes had started a certification program that allows companies to register and certify their extensions for the Kubernetes community. In one month over 30 companies had signed up for the program.
|
||||
|
||||
Goldberg went on to explain how the extensibility of Kubernetes was a hot topic in this year's KubeCon, and how Google and IBM were building a platform to manage and secure microservices using CRDs. Or how some developers were bringing machine-learning to Kubernetes, and others were demonstrating open service broker and the consumption of services on hybrid settings.
|
||||
|
||||
In conclusion, Goldberg said, extensibility is about empowerment. And, the extensibility of Kubernetes makes it a general purpose and easy to use platform for developers, which allows them to run any application.
|
||||
|
||||
You can watch the entire video below:
|
||||
|
||||
https://www.youtube.com/embed/1kjgwXP_N7A?enablejsapi=1
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.linux.com/blog/event/kubecon/2018/2/3-ways-extend-power-kubernetes
|
||||
|
||||
作者:[PAUL BROWN][a]
|
||||
译者:[译者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/users/bro66
|
||||
[1]:http://events17.linuxfoundation.org/events/kubecon-and-cloudnativecon-north-america
|
@ -1,66 +0,0 @@
|
||||
LKRG: Linux to Get a Loadable Kernel Module for Runtime Integrity Checking
|
||||
======
|
||||
![LKRG logo][1]
|
||||
|
||||
Members of the open source community are working on a new security-focused project for the Linux kernel. Named Linux Kernel Runtime Guard (LKRG), this is a loadable kernel module that will perform runtime integrity checking of the Linux kernel.
|
||||
|
||||
Its purpose is to detect exploitation attempts for known and unknwon security vulnerabilities against the Linux kernel and attempt to block attacks.
|
||||
|
||||
LKRG will also detect privilege escalation for running processes, and kill the running process before the exploit code runs.
|
||||
|
||||
### Project under development since 2011. First versions released.
|
||||
|
||||
Since the project is in such early development, current versions of LKRG will only report kernel integrity violations via kernel messages, but a full exploit mitigation system will be deployed as the system matures.
|
||||
|
||||
Work on this project started in 2011, and LKRG has gone through a "re-development" phase, as LKRG member Alexander Peslyak described the process.
|
||||
|
||||
The first public version of LKRG —LKRG v0.0— is now live and available for download on [this page][2]. A wiki is also available [here][3], and a [Patreon page][4] for supporting the project has also been set up.
|
||||
|
||||
While LKRG will remain an open source project, LKRG maintainers also have plans for an LKRG Pro version that will include distro-specific LKRG builds and support for the detection of specific exploits, such as container escapes. The team plans to use the funds from LKRG Pro to fund the rest of the project.
|
||||
|
||||
### LKRG is a kernel module. Not a patch.
|
||||
|
||||
A similar project is Additional Kernel Observer (AKO), but AKO differs from LKRG because it's a kernel load-on module and not a patch. The LKRG team chose to create a kernel module because patching the kernel has a direct impact on the security, system stability, and performance.
|
||||
|
||||
By offering a kernel module this also makes LKRG easier to deploy on a per-system basis without having to tinker with core kernel code, a very complicated and error-prone process.
|
||||
|
||||
LKRG kernel modules are currently available for main Linux distros such as RHEL7, OpenVZ 7, Virtuozzo 7, and Ubuntu 16.04 to latest mainlines.
|
||||
|
||||
### Not a perfect solution
|
||||
|
||||
But LKRG's creators are warning users not to consider their tool as unbreakable and 100% secure. They said LKRG is "bypassable by design," and only provides "security through diversity."
|
||||
|
||||
```
|
||||
While LKRG defeats many pre-existing exploits of Linux kernel vulnerabilities, and will likely defeat many future exploits (including of yet unknown vulnerabilities) that do not specifically attempt to bypass LKRG, it is bypassable by design (albeit sometimes at the expense of more complicated and/or less reliable exploits). Thus, it can be said that LKRG provides security through diversity, much like running an uncommon OS kernel would, yet without the usability drawbacks of actually running an uncommon OS.
|
||||
```
|
||||
|
||||
LKRG is similar to Windows-based antivirus software, which also works at the kernel level to detect exploits and malware. Nonetheless, the LKRG team says their product is much safer then antivirus and other endpoint security software because it has a much smaller codebase, hence a smaller footprint for introducing new bugs and vulnerabilities at the kernel level.
|
||||
|
||||
### Current LKRG version adds a 6.5% performance dip
|
||||
|
||||
Peslyak says LKRG is most suited for Linux machines that can't be rebooted right in the aftermath of a security flaw to patch the kernel. LKRG allows owners to continue to run the machine with a security measure in place until patches for critical vulnerabilities can be tested and deployed during planned maintenance windows.
|
||||
|
||||
Tests showed that installing LKRG v0.0 added a 6.5% performance impact, but Peslyak says this will be reduced as development moves forward.
|
||||
|
||||
Tests also showed that LKRG detected exploitation attempts for CVE-2014-9322 (BadIRET), CVE-2017-5123 (waitid(2) missing access_ok), and CVE-2017-6074 (use-after-free in DCCP protocol), but failed to detect CVE-2016-5195 (Dirty COW). The team said LKRG failed to spot the Dirty COW privilege escalation because of the previously mentioned "bypassable by design" strategy.
|
||||
|
||||
```
|
||||
In case of Dirty COW the LKRG "bypass" happened due to the nature of the bug and this being the way to exploit it, it's also a way for future exploits to bypass LKRG by similarly directly targeting userspace. It remains to be seen whether such exploits become common (unlikely unless LKRG or similar become popular?) and what (negative?) effect on their reliability this will have (for kernel vulnerabilities where directly targeting the userspace isn't essential and possibly not straightforward).
|
||||
```
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.bleepingcomputer.com/news/linux/lkrg-linux-to-get-a-loadable-kernel-module-for-runtime-integrity-checking/
|
||||
|
||||
作者:[Catalin Cimpanu][a]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://www.bleepingcomputer.com/author/catalin-cimpanu/
|
||||
[1]:https://www.bleepstatic.com/content/posts/2018/02/04/LKRG-logo.png
|
||||
[2]:http://www.openwall.com/lkrg/
|
||||
[3]:http://openwall.info/wiki/p_lkrg/Main
|
||||
[4]:https://www.patreon.com/p_lkrg
|
@ -1,3 +1,5 @@
|
||||
Translating by Flowsnow
|
||||
|
||||
Modern Web Automation With Python and Selenium – Real Python
|
||||
======
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
Leemeans translating
|
||||
Programming in Color with ncurses
|
||||
======
|
||||
In parts [one][1] and [two][2] of my article series about programming with the ncurses library, I introduced a few curses functions to draw text on the screen, query characters from the screen and read from the keyboard. To demonstrate several of these functions, I created a simple adventure game in curses that drew a game map and player character using simple characters. In this follow-up article, I show how to add color to a curses program.
|
||||
|
@ -1,340 +0,0 @@
|
||||
Translating by ghsgz | Simple TensorFlow Examples
|
||||
======
|
||||
|
||||
![](https://process.filestackapi.com/cache=expiry:max/resize=width:700/compress/XWiMrodDQb2Qg6RxyDDG)
|
||||
|
||||
In this post, we are going to see some TensorFlow examples and see how it’s easy to define tensors, perform math operations using tensors, and other machine learning examples.
|
||||
|
||||
## What is TensorFlow?
|
||||
|
||||
TensorFlow is a library which was developed by Google for solving complicated mathematical problems which takes much time.
|
||||
|
||||
Actually, TensorFlow can do many things like:
|
||||
|
||||
* Solving complex mathematical expressions.
|
||||
* Machine learning techniques, where you give it a sample of data for training, then you give another sample of data to predict the result based on the training data. This is the artificial intelligence!!
|
||||
* GPU support. You can use GPU (Graphical Processing Unit) instead of CPU for faster processing. There are two versions of TensorFlow, CPU version and GPU version.
|
||||
|
||||
|
||||
|
||||
Before we start working with TensorFlow examples, we need to know some basics.
|
||||
|
||||
## What is a Tensor?
|
||||
|
||||
The tensor is the main blocks of data that TensorFlow uses, it’s like the variables that TensorFlow uses to work with data. Each tensor has a dimension and a type.
|
||||
|
||||
The dimension is the rows and columns of the tensor, you can define one-dimensional tensor, two-dimensional tensor, and three-dimensional tensor as we will see later.
|
||||
|
||||
The type is the data type for the elements of the tensor.
|
||||
|
||||
## Define one-dimensional Tensor
|
||||
|
||||
To define a tensor, we will create a NumPy array or a [Python list][1] and convert it to a tensor using the tf_convert_to_tensor function.
|
||||
|
||||
We will use NumPy to create an array like this:
|
||||
```
|
||||
import numpy as np arr = np.array([1, 5.5, 3, 15, 20])
|
||||
|
||||
arr = np.array([1, 5.5, 3, 15, 20])
|
||||
|
||||
```
|
||||
|
||||
You can see from the results the dimension and shape of the array.
|
||||
```
|
||||
import numpy as np
|
||||
|
||||
arr = np.array([1, 5.5, 3, 15, 20])
|
||||
|
||||
print(arr)
|
||||
|
||||
print (arr.ndim)
|
||||
|
||||
print (arr.shape)
|
||||
|
||||
print (arr.dtype)
|
||||
|
||||
```
|
||||
|
||||
It looks like the Python list but here there is no comma between the items.
|
||||
|
||||
Now we will convert this array to a tensor using tf_convert_to_tensor function.
|
||||
```
|
||||
import numpy as np
|
||||
|
||||
import tensorflow as tf
|
||||
|
||||
arr = np.array([1, 5.5, 3, 15, 20])
|
||||
|
||||
tensor = tf.convert_to_tensor(arr,tf.float64)
|
||||
|
||||
print(tensor)
|
||||
|
||||
```
|
||||
|
||||
From the results, you can see the tensor definition, but you can’t see the tensor elements.
|
||||
|
||||
Well, to see the tensor elements, you can run a session like this:
|
||||
```
|
||||
import numpy as np
|
||||
|
||||
import tensorflow as tf
|
||||
|
||||
arr = np.array([1, 5.5, 3, 15, 20])
|
||||
|
||||
tensor = tf.convert_to_tensor(arr,tf.float64)
|
||||
|
||||
sess = tf.Session()
|
||||
|
||||
print(sess.run(tensor))
|
||||
|
||||
print(sess.run(tensor[1]))
|
||||
|
||||
```
|
||||
|
||||
## Define Two-dimensional Tensor
|
||||
|
||||
The same way as the one-dimensional array, but this time we will define the array like this:
|
||||
|
||||
```
|
||||
arr = np.array([(1, 5.5, 3, 15, 20),(10, 20, 30, 40, 50), (60, 70, 80, 90, 100)])
|
||||
```
|
||||
|
||||
And you can convert it to a tensor like this:
|
||||
```
|
||||
import numpy as np
|
||||
|
||||
import tensorflow as tf
|
||||
|
||||
arr = np.array([(1, 5.5, 3, 15, 20),(10, 20, 30, 40, 50), (60, 70, 80, 90, 100)])
|
||||
|
||||
tensor = tf.convert_to_tensor(arr)
|
||||
|
||||
sess = tf.Session()
|
||||
|
||||
print(sess.run(tensor))
|
||||
|
||||
```
|
||||
|
||||
Now you know how to define tensors, what about performing some math operations between them?
|
||||
|
||||
## Performing Math on Tensors
|
||||
|
||||
Suppose that we have 2 arrays like this:
|
||||
```
|
||||
arr1 = np.array([(1,2,3),(4,5,6)])
|
||||
|
||||
arr2 = np.array([(7,8,9),(10,11,12)])
|
||||
|
||||
```
|
||||
|
||||
We need to get the sum of them. You can perform many math operations using TensorFlow.
|
||||
|
||||
You can use the add function like this:
|
||||
```
|
||||
import numpy as np
|
||||
|
||||
import tensorflow as tf
|
||||
|
||||
arr1 = np.array([(1,2,3),(4,5,6)])
|
||||
|
||||
arr2 = np.array([(7,8,9),(10,11,12)])
|
||||
|
||||
arr3 = tf.add(arr1,arr2)
|
||||
|
||||
sess = tf.Session()
|
||||
|
||||
tensor = sess.run(arr3)
|
||||
|
||||
print(tensor)
|
||||
|
||||
```
|
||||
|
||||
You can multiply arrays like this:
|
||||
```
|
||||
import numpy as np
|
||||
|
||||
import tensorflow as tf
|
||||
|
||||
arr1 = np.array([(1,2,3),(4,5,6)])
|
||||
|
||||
arr2 = np.array([(7,8,9),(10,11,12)])
|
||||
|
||||
arr3 = tf.multiply(arr1,arr2)
|
||||
|
||||
sess = tf.Session()
|
||||
|
||||
tensor = sess.run(arr3)
|
||||
|
||||
print(tensor)
|
||||
|
||||
```
|
||||
|
||||
Now you got the idea.
|
||||
|
||||
## Three-dimensional Tensor
|
||||
|
||||
We saw how to work with one and two-dimensional tensors, now we will see the three-dimensional tensors, but this time we won’t use numbers, we will use an RGB image where each piece of the image is specified by x, y, and z coordinates.
|
||||
|
||||
These coordinates are the width, height, and color depth.
|
||||
|
||||
First, let’s import the image using matplotlib. You can install matplotlib [using pip][2] if it’s not installed on your system.
|
||||
|
||||
Now, put your file in the same directory with your Python file and import the image using matplotlib like this:
|
||||
```
|
||||
import matplotlib.image as img
|
||||
|
||||
myfile = "likegeeks.png"
|
||||
|
||||
myimage = img.imread(myfile)
|
||||
|
||||
print(myimage.ndim)
|
||||
|
||||
print(myimage.shape)
|
||||
|
||||
```
|
||||
|
||||
As you can see, it’s a three-dimensional image where the width is 150 and the height is 150 and the color depth is 3.
|
||||
|
||||
You can view the image like this:
|
||||
```
|
||||
import matplotlib.image as img
|
||||
|
||||
import matplotlib.pyplot as plot
|
||||
|
||||
myfile = "likegeeks.png"
|
||||
|
||||
myimage = img.imread(myfile)
|
||||
|
||||
plot.imshow(myimage)
|
||||
|
||||
plot.show()
|
||||
|
||||
```
|
||||
|
||||
Cool!!
|
||||
|
||||
What about manipulating the image using TensorFlow? Super easy.
|
||||
|
||||
## Crop Or Slice Image Using TensorFlow
|
||||
|
||||
First, we put the values on a placeholder like this:
|
||||
```
|
||||
myimage = tf.placeholder("int32",[None,None,3])
|
||||
|
||||
```
|
||||
|
||||
To slice the image, we will use the slice operator like this:
|
||||
```
|
||||
cropped = tf.slice(myimage,[10,0,0],[16,-1,-1])
|
||||
|
||||
```
|
||||
|
||||
Finally, run the session:
|
||||
```
|
||||
result = sess.run(cropped, feed\_dict={slice: myimage})
|
||||
|
||||
```
|
||||
|
||||
Then you can see the result image using matplotlib.
|
||||
|
||||
So the whole code will be like this:
|
||||
```
|
||||
import tensorflow as tf
|
||||
|
||||
import matplotlib.image as img
|
||||
|
||||
import matplotlib.pyplot as plot
|
||||
|
||||
myfile = "likegeeks.png"
|
||||
|
||||
myimage = img.imread(myfile)
|
||||
|
||||
slice = tf.placeholder("int32",[None,None,3])
|
||||
|
||||
cropped = tf.slice(myimage,[10,0,0],[16,-1,-1])
|
||||
|
||||
sess = tf.Session()
|
||||
|
||||
result = sess.run(cropped, feed_dict={slice: myimage})
|
||||
|
||||
plot.imshow(result)
|
||||
|
||||
plot.show()
|
||||
|
||||
```
|
||||
|
||||
Awesome!!
|
||||
|
||||
## Transpose Images using TensorFlow
|
||||
|
||||
In this TensorFlow example, we will do a simple transformation using TensorFlow.
|
||||
|
||||
First, specify the input image and initialize TensorFlow variables:
|
||||
```
|
||||
myfile = "likegeeks.png"
|
||||
|
||||
myimage = img.imread(myfile)
|
||||
|
||||
image = tf.Variable(myimage,name='image')
|
||||
|
||||
vars = tf.global_variables_initializer()
|
||||
|
||||
```
|
||||
|
||||
Then we will use the transpose function which flips the 0 and 1 axes of the input grid:
|
||||
```
|
||||
sess = tf.Session()
|
||||
|
||||
flipped = tf.transpose(image, perm=[1,0,2])
|
||||
|
||||
sess.run(vars)
|
||||
|
||||
result=sess.run(flipped)
|
||||
|
||||
```
|
||||
|
||||
Then you can show the resulting image using matplotlib.
|
||||
```
|
||||
import tensorflow as tf
|
||||
|
||||
import matplotlib.image as img
|
||||
|
||||
import matplotlib.pyplot as plot
|
||||
|
||||
myfile = "likegeeks.png"
|
||||
|
||||
myimage = img.imread(myfile)
|
||||
|
||||
image = tf.Variable(myimage,name='image')
|
||||
|
||||
vars = tf.global_variables_initializer()
|
||||
|
||||
sess = tf.Session()
|
||||
|
||||
flipped = tf.transpose(image, perm=[1,0,2])
|
||||
|
||||
sess.run(vars)
|
||||
|
||||
result=sess.run(flipped)
|
||||
|
||||
plot.imshow(result)
|
||||
|
||||
plot.show()
|
||||
|
||||
```
|
||||
|
||||
All these TensorFlow examples show you how easy it’s to work with TensorFlow.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.codementor.io/likegeeks/define-and-use-tensors-using-simple-tensorflow-examples-ggdgwoy4u
|
||||
|
||||
作者:[LikeGeeks][a]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://www.codementor.io/likegeeks
|
||||
[1]:https://likegeeks.com/python-list-functions/
|
||||
[2]:https://likegeeks.com/import-create-install-reload-alias-python-modules/#Install-Python-Modules-Using-pip
|
155
sources/tech/20180208 Advanced Dnsmasq Tips and Tricks.md
Normal file
155
sources/tech/20180208 Advanced Dnsmasq Tips and Tricks.md
Normal file
@ -0,0 +1,155 @@
|
||||
Advanced Dnsmasq Tips and Tricks
|
||||
======
|
||||
|
||||
!](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/banner_3.25.47_pm.png?itok=2YaDe86d)
|
||||
|
||||
Many people know and love Dnsmasq and rely on it for their local name services. Today we look at advanced configuration file management, how to test your configurations, some basic security, DNS wildcards, speedy DNS configuration, and some other tips and tricks. Next week, we'll continue with a detailed look at how to configure DNS and DHCP.
|
||||
|
||||
### Testing Configurations
|
||||
|
||||
When you're testing new configurations, you should run Dnsmasq from the command line, rather than as a daemon. This example starts it without launching the daemon, prints command output, and logs all activity:
|
||||
```
|
||||
# dnsmasq --no-daemon --log-queries
|
||||
dnsmasq: started, version 2.75 cachesize 150
|
||||
dnsmasq: compile time options: IPv6 GNU-getopt
|
||||
DBus i18n IDN DHCP DHCPv6 no-Lua TFTP conntrack
|
||||
ipset auth DNSSEC loop-detect inotify
|
||||
dnsmasq: reading /etc/resolv.conf
|
||||
dnsmasq: using nameserver 192.168.0.1#53
|
||||
dnsmasq: read /etc/hosts - 9 addresses
|
||||
|
||||
```
|
||||
|
||||
You can see tons of useful information in this small example, including version, compiled options, system name service files, and its listening address. Ctrl+c stops it. By default, Dnsmasq does not have its own log file, so entries are dumped into multiple locations in `/var/log`. You can use good old `grep` to find Dnsmasq log entries. This example searches `/var/log` recursively, prints the line numbers after the filenames, and excludes `/var/log/dist-upgrade`:
|
||||
```
|
||||
# grep -ir --exclude-dir=dist-upgrade dnsmasq /var/log/
|
||||
|
||||
```
|
||||
|
||||
Note the fun grep gotcha with `--exclude-dir=`: Don't specify the full path, but just the directory name.
|
||||
|
||||
You can give Dnsmasq its own logfile with this command-line option, using whatever file you want:
|
||||
```
|
||||
# dnsmasq --no-daemon --log-queries --log-facility=/var/log/dnsmasq.log
|
||||
|
||||
```
|
||||
|
||||
Or enter it in your Dnsmasq configuration file as `log-facility=/var/log/dnsmasq.log`.
|
||||
|
||||
### Configuration Files
|
||||
|
||||
Dnsmasq is configured in `/etc/dnsmasq.conf`. Your Linux distribution may also use `/etc/default/dnsmasq`, `/etc/dnsmasq.d/`, and `/etc/dnsmasq.d-available/`. (No, there cannot be a universal method, as that is against the will of the Linux Cat Herd Ruling Cabal.) You have a fair bit of flexibility to organize your Dnsmasq configuration in a way that pleases you.
|
||||
|
||||
`/etc/dnsmasq.conf` is the grandmother as well as the boss. Dnsmasq reads it first at startup. `/etc/dnsmasq.conf` can call other configuration files with the `conf-file=` option, for example `conf-file=/etc/dnsmasqextrastuff.conf`, and directories with the `conf-dir=` option, e.g. `conf-dir=/etc/dnsmasq.d`.
|
||||
|
||||
Whenever you make a change in a configuration file, you must restart Dnsmasq.
|
||||
|
||||
You may include or exclude configuration files by extension. The asterisk means include, and the absence of the asterisk means exclude:
|
||||
```
|
||||
conf-dir=/etc/dnsmasq.d/,*.conf, *.foo
|
||||
conf-dir=/etc/dnsmasq.d,.old, .bak, .tmp
|
||||
|
||||
```
|
||||
|
||||
You may store your host configurations in multiple files with the `--addn-hosts=` option.
|
||||
|
||||
Dnsmasq includes a syntax checker:
|
||||
```
|
||||
$ dnsmasq --test
|
||||
dnsmasq: syntax check OK.
|
||||
|
||||
```
|
||||
|
||||
### Useful Configurations
|
||||
|
||||
Always include these lines:
|
||||
```
|
||||
domain-needed
|
||||
bogus-priv
|
||||
|
||||
```
|
||||
|
||||
These prevent packets with malformed domain names and packets with private IP addresses from leaving your network.
|
||||
|
||||
This limits your name services exclusively to Dnsmasq, and it will not use `/etc/resolv.conf` or any other system name service files:
|
||||
```
|
||||
no-resolv
|
||||
|
||||
```
|
||||
|
||||
Reference other name servers. The first example is for a local private domain. The second and third examples are OpenDNS public servers:
|
||||
```
|
||||
server=/fooxample.com/192.168.0.1
|
||||
server=208.67.222.222
|
||||
server=208.67.220.220
|
||||
|
||||
```
|
||||
|
||||
Or restrict just local domains while allowing external lookups for other domains. These are answered only from `/etc/hosts` or DHCP:
|
||||
```
|
||||
local=/mehxample.com/
|
||||
local=/fooxample.com/
|
||||
|
||||
```
|
||||
|
||||
Restrict which network interfaces Dnsmasq listens to:
|
||||
```
|
||||
interface=eth0
|
||||
interface=wlan1
|
||||
|
||||
```
|
||||
|
||||
Dnsmasq, by default, reads and uses `/etc/hosts`. This is a fabulously fast way to configure a lot of hosts, and the `/etc/hosts` file only has to exist on the same computer as Dnsmasq. You can make the process even faster by entering only the hostnames in `/etc/hosts`, and use Dnsmasq to add the domain. `/etc/hosts` looks like this:
|
||||
```
|
||||
127.0.0.1 localhost
|
||||
192.168.0.1 host2
|
||||
192.168.0.2 host3
|
||||
192.168.0.3 host4
|
||||
|
||||
```
|
||||
|
||||
Then add these lines to `dnsmasq.conf`, using your own domain, of course:
|
||||
```
|
||||
expand-hosts
|
||||
domain=mehxample.com
|
||||
|
||||
```
|
||||
|
||||
Dnsmasq will automatically expand the hostnames to fully qualified domain names, for example, host2 to host2.mehxample.com.
|
||||
|
||||
### DNS Wildcards
|
||||
|
||||
In general, DNS wildcards are not a good practice because they invite abuse. But there are times when they are useful, such as inside the nice protected confines of your LAN. For example, Kubernetes clusters are considerably easier to manage with wildcard DNS, unless you enjoy making DNS entries for your hundreds or thousands of applications. Suppose your Kubernetes domain is mehxample.com; in Dnsmasq a wildcard that resolves all requests to mehxample.com looks like this:
|
||||
```
|
||||
address=/mehxample.com/192.168.0.5
|
||||
|
||||
```
|
||||
|
||||
The address to use in this case is the public IP address for your cluster. This answers requests for hosts and subdomains in mehxample.com, except for any that are already configured in DHCP or `/etc/hosts`.
|
||||
|
||||
Next week, we'll go into more detail on managing DNS and DHCP, including different options for different subnets, and providing authoritative name services.
|
||||
|
||||
### Additional Resources
|
||||
|
||||
* [DNS Spoofing with Dnsmasq][1]
|
||||
|
||||
* [Dnsmasq For Easy LAN Name Services][2]
|
||||
|
||||
* [Dnsmasq][3]
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.linux.com/learn/intro-to-linux/2018/2/advanced-dnsmasq-tips-and-tricks
|
||||
|
||||
作者:[CARLA SCHRODER][a]
|
||||
译者:[译者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/users/cschroder
|
||||
[1]:https://www.linux.com/learn/intro-to-linux/2017/7/dns-spoofing-dnsmasq
|
||||
[2]:https://www.linux.com/learn/dnsmasq-easy-lan-name-services
|
||||
[3]:http://www.thekelleys.org.uk/dnsmasq/doc.html
|
118
sources/tech/20180208 How to Create a Sudo User on CentOS 7.md
Normal file
118
sources/tech/20180208 How to Create a Sudo User on CentOS 7.md
Normal file
@ -0,0 +1,118 @@
|
||||
How to Create a Sudo User on CentOS 7
|
||||
======
|
||||
![How to create a sudo user on CentOS 7][1]
|
||||
|
||||
We’ll guide you, how to create a sudo user on CentOS 7. Sudo is a Linux command line program that allows you to execute commands as superuser or another system user. The configuration file offers detailed access permissions, including enabling commands only from the invoking terminal; requiring a password per user or group; requiring re-entry of a password every time or never requiring a password at all for a particular command line. It can also be configured to permit passing arguments or multiple commands. In this tutorial we will show you how to create a sudo user on CentOS 7.
|
||||
|
||||
### Steps to Create a New Sudo User on CentOS 7
|
||||
|
||||
#### 1. Connect via SSH
|
||||
|
||||
First of all, [connect to your server via SSH][2]. Once you are logged in, you need to add a new system user.
|
||||
|
||||
#### 2. Add New User in CentOS
|
||||
|
||||
You can add a new system user using the following command:
|
||||
```
|
||||
# adduser newuser
|
||||
|
||||
```
|
||||
|
||||
You need to replace `newuser` with the name of the user you want to add. Also, you need to set up a password for the newly added user.
|
||||
|
||||
#### 3. Create a Strong Password
|
||||
|
||||
To set up a password you can use the following command:
|
||||
```
|
||||
# passwd newuser
|
||||
|
||||
```
|
||||
|
||||
Make sure you are using a [strong password][3], otherwise the password will fail against the dictionary check. You will be asked to enter the password again and once you enter it you will be notified that the authentication tokens are updated successfully:
|
||||
```
|
||||
# passwd newuser
|
||||
Changing password for user newuser.
|
||||
New password:
|
||||
Retype new password:
|
||||
passwd: all authentication tokens updated successfully.
|
||||
|
||||
```
|
||||
|
||||
#### 4. Add User to the Wheel Group in CentOS
|
||||
|
||||
The wheel group is a special user group that allows all members in the group to run all commands. Therefore, you need to add the new user to this group so it can run commands as superuser. You can do that by using the following command:
|
||||
```
|
||||
# usermod -aG wheel newuser
|
||||
|
||||
```
|
||||
|
||||
Again, make sure you are using the name of the actual user instead of `newuser`.
|
||||
Now, use `visudo` to open and edit the `/etc/sudoers` file. Make sure that the line that starts with `%wheel` is not commented. It should look exactly like this:
|
||||
```
|
||||
### Allows people in group wheel to run all commands
|
||||
%wheel ALL=(ALL) ALL
|
||||
|
||||
```
|
||||
|
||||
Now that your new user is set up you can switch to that user and test if everything is OK.
|
||||
|
||||
#### 5. Switch to the sudo User
|
||||
|
||||
To switch to the new user, run the following command:
|
||||
```
|
||||
# su - newuser
|
||||
|
||||
```
|
||||
|
||||
Now run a command that usually doesn’t work for regular users like the one below:
|
||||
```
|
||||
$ ls -la /root/
|
||||
|
||||
```
|
||||
|
||||
You will get the following error message:
|
||||
```
|
||||
ls: cannot open directory /root/: Permission denied
|
||||
|
||||
```
|
||||
|
||||
Try to run the same command, now with using `sudo`
|
||||
```
|
||||
$ sudo ls -ls /root/
|
||||
|
||||
```
|
||||
|
||||
You will need to enter the password for the new user to proceed. If everything is OK, the command will list all the content in the `/root` directory. Another way to test this is to run the following command:
|
||||
```
|
||||
$ sudo whoami
|
||||
|
||||
```
|
||||
|
||||
The output of the command should be similar to the one below:
|
||||
```
|
||||
$ sudo whoami
|
||||
root
|
||||
|
||||
```
|
||||
|
||||
Congratulations, now you have a sudo user which you can use to manage your CentOS 7, operating system.
|
||||
|
||||
Of course, you don’t have to create a sudo user on CentOS 7, if you use one of our [CentOS 7 Hosting][4] services, in which case you can simply ask our expert Linux admins to create a sudo user on CentOS 7, for you. They are available 24×7 and will take care of your request immediately.
|
||||
|
||||
**PS**. If you liked this post on **how to create a sudo user on CentOS 7** , please share it with your friends on the social networks using the buttons on the left or simply leave a reply below. Thanks.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.rosehosting.com/blog/how-to-create-a-sudo-user-on-centos-7/
|
||||
|
||||
作者:[RoseHosting][a]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://www.rosehosting.com
|
||||
[1]:https://www.rosehosting.com/blog/wp-content/uploads/2018/02/How-to-create-a-sudo-user-on-CentOS-7.jpg
|
||||
[2]:https://www.rosehosting.com/blog/connect-to-your-linux-vps-via-ssh/
|
||||
[3]:https://www.rosehosting.com/blog/generate-password-linux-command-line/
|
||||
[4]:https://www.rosehosting.com/centos-vps.html
|
@ -0,0 +1,271 @@
|
||||
How to Install and Configure XWiki on Ubuntu 16.04
|
||||
======
|
||||
|
||||
XWiki is a free and open source wiki software written in Java runs on a servlet container like Tomcat, JBoss etc. XWiki uses databases such as MySQL or PostgreSQL to store its information. XWiki allows us to store structured data and execute the server script within wiki interface. You can host multiple blogs and manage or view your files and folders using XWiki.
|
||||
|
||||
XWiki comes with lots of features, some of them are listed below:
|
||||
|
||||
* Supports version control and ACL.
|
||||
* Allows you to search the full wiki using wildcards.
|
||||
* Easily export wiki pages to PDF, ODT, RTF, XML and HTML.
|
||||
* Content organization and content import.
|
||||
* Page editing using WYSIWYG editor.
|
||||
|
||||
|
||||
|
||||
### Requirements
|
||||
|
||||
* A server running Ubuntu 16.04.
|
||||
* A non-root user with sudo privileges.
|
||||
|
||||
|
||||
|
||||
Before starting, you will need to update the Ubuntu repository to the latest version. You can do this using the following command:
|
||||
|
||||
```
|
||||
sudo apt-get update -y
|
||||
sudo apt-get upgrade -y
|
||||
```
|
||||
|
||||
Once the repository is updated, restart the system to apply all the updates.
|
||||
|
||||
### Install Java
|
||||
|
||||
Xwiki is a Java-based application, so you will need to install Java 8 first. By default Java 8 is not available in the Ubuntu repository. You can install Java 8 by adding the webupd8team PPA repository to your system.
|
||||
|
||||
First, add the PPA by running the following command:
|
||||
|
||||
```
|
||||
sudo add-apt-repository ppa:webupd8team/java
|
||||
```
|
||||
|
||||
Next, update the repository with the following command:
|
||||
|
||||
```
|
||||
sudo apt-get update -y
|
||||
```
|
||||
|
||||
Once the repository is up to date, you can install Java 8 by running the following command:
|
||||
|
||||
```
|
||||
sudo apt-get install oracle-java8-installer -y
|
||||
```
|
||||
|
||||
After installing Java, you can check the version of Java with the following command:
|
||||
|
||||
```
|
||||
java -version
|
||||
```
|
||||
|
||||
You should see the following output:
|
||||
```
|
||||
Java version "1.8.0_91"
|
||||
Java(TM) SE Runtime Environment (build 1.8.0_91-b14)
|
||||
Java HotSpot(TM) 64-Bit Server VM (build 25.91-b14, mixed mode)
|
||||
|
||||
```
|
||||
|
||||
### Download and Install Xwiki
|
||||
|
||||
Next, you will need to download the setup file provided by XWiki. You can download it using the following command:
|
||||
|
||||
```
|
||||
wget <http://download.forge.ow2.org/xwiki/xwiki-enterprise-installer-generic-8.1-standard.jar>
|
||||
```
|
||||
|
||||
Once the download is completed, you can install the downloaded package file using the java command as shown below:
|
||||
|
||||
```
|
||||
sudo java -jar xwiki-enterprise-installer-generic-8.1-standard.jar
|
||||
```
|
||||
|
||||
You should see the following output:
|
||||
```
|
||||
28 Jan, 2018 6:57:37 PM INFO: Logging initialized at level 'INFO'
|
||||
28 Jan, 2018 6:57:37 PM INFO: Commandline arguments:
|
||||
28 Jan, 2018 6:57:37 PM INFO: Detected platform: ubuntu_linux,version=3.19.0-25-generic,arch=x64,symbolicName=null,javaVersion=1.7.0_151
|
||||
28 Jan, 2018 6:57:37 PM WARNING: Failed to determine hostname and IP address
|
||||
Welcome to the installation of XWiki Enterprise 8.1!
|
||||
The homepage is at: http://xwiki.org/
|
||||
|
||||
Press 1 to continue, 2 to quit, 3 to redisplay
|
||||
|
||||
```
|
||||
|
||||
Now, press **`1`** to continue the installation, you should see the following output:
|
||||
```
|
||||
Please read the following information:
|
||||
|
||||
XWiki Enterprise - Readme
|
||||
|
||||
|
||||
XWiki Enterprise Overview
|
||||
XWiki Enterprise is a second generation Wiki engine, features professional features like
|
||||
Wiki, Blog, Comments, User Rights, LDAP Authentication, PDF Export, and a lot more.
|
||||
XWiki Enterprise also includes an advanced form and scripting engine which makes it an ideal
|
||||
development environment for constructing data-based intranet applications. It has powerful
|
||||
extensibility features, supports scripting, extensions and is based on a highly modular
|
||||
architecture. The scripting engine allows to access a powerful API for accessing the XWiki
|
||||
repository in read and write mode.
|
||||
XWiki Enterprise is used by major companies around the world and has strong
|
||||
Support for a professional usage of XWiki.
|
||||
Pointers
|
||||
Here are some pointers to get you started with XWiki once you have finished installing it:
|
||||
|
||||
The documentation can be found on the XWiki.org web site
|
||||
If you notice any issue please file a an issue in our issue tracker
|
||||
If you wish to talk to XWiki users or developers please use our
|
||||
Mailing lists & Forum
|
||||
You can also access XWiki's
|
||||
source code
|
||||
If you need commercial support please visit the
|
||||
Support page
|
||||
|
||||
|
||||
|
||||
Press 1 to continue, 2 to quit, 3 to redisplay
|
||||
|
||||
```
|
||||
|
||||
Now, press **`1`** to continue the installation, you should see the following output:
|
||||
```
|
||||
See the NOTICE file distributed with this work for additional
|
||||
information regarding copyright ownership.
|
||||
This is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of
|
||||
the License, or (at your option) any later version.
|
||||
This software 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
|
||||
Lesser General Public License for more details.
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this software; if not, write to the Free
|
||||
Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
02110-1301 USA, or see the FSF site: http://www.fsf.org.
|
||||
|
||||
Press 1 to accept, 2 to reject, 3 to redisplay
|
||||
|
||||
```
|
||||
|
||||
Now, press **`1`** to accept the license agreement, you should see the following output:
|
||||
```
|
||||
Select the installation path: [/usr/local/XWiki Enterprise 8.1]
|
||||
|
||||
Press 1 to continue, 2 to quit, 3 to redisplay
|
||||
|
||||
```
|
||||
|
||||
Now, press enter and press **1** to select default installation path, you should see the following output:
|
||||
```
|
||||
[x] Pack 'Core' required
|
||||
????????????????????????????????????????????????????????????????????????????????
|
||||
[x] Include optional pack 'Default Wiki'
|
||||
????????????????????????????????????????????????????????????????????????????????
|
||||
Enter Y for Yes, N for No:
|
||||
Y
|
||||
Press 1 to continue, 2 to quit, 3 to redisplay
|
||||
|
||||
```
|
||||
|
||||
Now, press **`Y`** and press **`1`** to continue the installation, you should see the following output:
|
||||
```
|
||||
[ Starting to unpack ]
|
||||
[ Processing package: Core (1/2) ]
|
||||
[ Processing package: Default Wiki (2/2) ]
|
||||
[ Unpacking finished ]
|
||||
|
||||
```
|
||||
|
||||
Now, you will be asked to create shortcuts for the user, you can press ' **`Y'`** to add them. Next, you will be asked to generate an automatic installation script, just press Enter to select default value, once the installation is finished, you should see the following output:
|
||||
```
|
||||
????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
|
||||
Generate an automatic installation script
|
||||
????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
|
||||
Enter Y for Yes, N for No:
|
||||
Y
|
||||
Select the installation script (path must be absolute)[/usr/local/XWiki Enterprise 8.1/auto-install.xml]
|
||||
|
||||
Installation was successful
|
||||
application installed on /usr/local/XWiki Enterprise 8.1
|
||||
[ Writing the uninstaller data ... ]
|
||||
[ Console installation done ]
|
||||
|
||||
```
|
||||
|
||||
Now, XWiki is installed on your system, it's time to start XWiki startup script as shown below:
|
||||
|
||||
```
|
||||
cd /usr/local/XWiki Enterprise 8.1
|
||||
sudo bash start_xwiki.sh
|
||||
```
|
||||
|
||||
Please, wait for sometime to start processes. Now, you should see some messages on terminal as shown below:
|
||||
```
|
||||
start_xwiki.sh: 79: start_xwiki.sh:
|
||||
Starting Jetty on port 8080, please wait...
|
||||
2018-01-28 19:12:41.842:INFO::main: Logging initialized @1266ms
|
||||
2018-01-28 19:12:42.905:INFO:oejs.Server:main: jetty-9.2.13.v20150730
|
||||
2018-01-28 19:12:42.956:INFO:oejs.AbstractNCSARequestLog:main: Opened /usr/local/XWiki Enterprise 8.1/data/logs/2018_01_28.request.log
|
||||
2018-01-28 19:12:42.965:INFO:oejdp.ScanningAppProvider:main: Deployment monitor [file:/usr/local/XWiki%20Enterprise%208.1/jetty/contexts/] at interval 0
|
||||
2018-01-28 19:13:31,485 [main] INFO o.x.s.s.i.EmbeddedSolrInstance - Starting embedded Solr server...
|
||||
2018-01-28 19:13:31,507 [main] INFO o.x.s.s.i.EmbeddedSolrInstance - Using Solr home directory: [data/solr]
|
||||
2018-01-28 19:13:43,371 [main] INFO o.x.s.s.i.EmbeddedSolrInstance - Started embedded Solr server.
|
||||
2018-01-28 19:13:46.556:INFO:oejsh.ContextHandler:main: Started [email protected]{/xwiki,file:/usr/local/XWiki%20Enterprise%208.1/webapps/xwiki/,AVAILABLE}{/xwiki}
|
||||
2018-01-28 19:13:46.697:INFO:oejsh.ContextHandler:main: Started [email protected]{/,file:/usr/local/XWiki%20Enterprise%208.1/webapps/root/,AVAILABLE}{/root}
|
||||
2018-01-28 19:13:46.776:INFO:oejs.ServerConnector:main: Started [email protected]{HTTP/1.1}{0.0.0.0:8080}
|
||||
|
||||
```
|
||||
|
||||
XWiki is now up and running, it's time to access XWiki web interface.
|
||||
|
||||
### Access XWiki
|
||||
|
||||
XWiki runs on port **8080** , so you will need to allow port 8080 through the firewall. First, enable the UFW firewall with the following command:
|
||||
|
||||
```
|
||||
sudo ufw enable
|
||||
```
|
||||
|
||||
Next, allow port **8080** through the UFW firewall with the following command:
|
||||
|
||||
```
|
||||
sudo ufw allow 8080/tcp
|
||||
```
|
||||
|
||||
Next, reload the firewall rules to apply all the changes by running the following command:
|
||||
|
||||
```
|
||||
sudo ufw reload
|
||||
```
|
||||
|
||||
You can get the status of the UFW firewall with the following command:
|
||||
|
||||
```
|
||||
sudo ufw status
|
||||
```
|
||||
|
||||
Now, open your web browser and type the URL **<http://your-server-ip:8080>** , you will be redirected to the XWiki home page as shown below:
|
||||
|
||||
[![XWiki Dashboard][1]][2]
|
||||
|
||||
You can stop the XWiki server at any time by pressing **`Ctrl + C`** button in the terminal.
|
||||
|
||||
### Conclusion
|
||||
|
||||
Congratulations! you have successfully installed and configured XWiki on Ubuntu 16.04 server. I hope you can now easily host your own wiki site using XWiki on Ubuntu 16.04 server. For more information, you can check the XWiki official documentation page at <https://www.xwiki.org/xwiki/bin/view/Documentation/>. Feel free to comments me if you have any questions.
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.howtoforge.com/tutorial/how-to-install-and-configure-xwiki-on-ubuntu-1604/
|
||||
|
||||
作者:[Hitesh Jethva][a]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://www.howtoforge.com
|
||||
[1]:https://www.howtoforge.com/images/how_to_install_and_configure_xwiki_on_ubuntu_1604/Screenshot-of-xwiki-dashboard.png
|
||||
[2]:https://www.howtoforge.com/images/how_to_install_and_configure_xwiki_on_ubuntu_1604/big/Screenshot-of-xwiki-dashboard.png
|
@ -1,198 +0,0 @@
|
||||
Python Global, Local and Nonlocal variables (With Examples)
|
||||
======
|
||||
### Global Variables
|
||||
|
||||
In Python, a variable declared outside of the function or in global scope is known as global variable. This means, global variable can be accessed inside or outside of the function.
|
||||
|
||||
Let's see an example on how a global variable is created in Python.
|
||||
|
||||
#### Example 1: Create a Global Variable
|
||||
```
|
||||
x = "global"
|
||||
|
||||
def foo():
|
||||
print("x inside :", x)
|
||||
|
||||
foo()
|
||||
print("x outside:", x)
|
||||
|
||||
```
|
||||
|
||||
When we run the code, the will output be:
|
||||
```
|
||||
x inside : global
|
||||
x outside: global
|
||||
|
||||
```
|
||||
|
||||
In above code, we created x as a global variable and defined a `foo()` to print the global variable x. Finally, we call the `foo()` which will print the value of x.
|
||||
|
||||
What if you want to change value of x inside a function?
|
||||
```
|
||||
x = "global"
|
||||
|
||||
def foo():
|
||||
x = x * 2
|
||||
print(x)
|
||||
foo()
|
||||
|
||||
```
|
||||
|
||||
When we run the code, the will output be:
|
||||
```
|
||||
UnboundLocalError: local variable 'x' referenced before assignment
|
||||
|
||||
```
|
||||
|
||||
The output shows an error because Python treats x as a local variable and x is also not defined inside `foo()`.
|
||||
|
||||
To make this work we use `global` keyword, to learn more visit [Python Global Keyword][1].
|
||||
|
||||
### Local Variables
|
||||
|
||||
A variable declared inside the function's body or in the local scope is known as local variable.
|
||||
|
||||
#### Example 2: Accessing local variable outside the scope
|
||||
```
|
||||
def foo():
|
||||
y = "local"
|
||||
|
||||
foo()
|
||||
print(y)
|
||||
|
||||
```
|
||||
|
||||
When we run the code, the will output be:
|
||||
```
|
||||
NameError: name 'y' is not defined
|
||||
|
||||
```
|
||||
|
||||
The output shows an error, because we are trying to access a local variable y in a global scope whereas the local variable only works inside `foo() `or local scope.
|
||||
|
||||
Let's see an example on how a local variable is created in Python.
|
||||
|
||||
#### Example 3: Create a Local Variable
|
||||
|
||||
Normally, we declare a variable inside the function to create a local variable.
|
||||
```
|
||||
def foo():
|
||||
y = "local"
|
||||
print(y)
|
||||
|
||||
foo()
|
||||
|
||||
```
|
||||
|
||||
When we run the code, it will output:
|
||||
```
|
||||
local
|
||||
|
||||
```
|
||||
|
||||
Let's take a look to the earlier problem where x was a global variable and we wanted to modify x inside `foo()`.
|
||||
|
||||
### Global and local variables
|
||||
|
||||
Here, we will show how to use global variables and local variables in the same code.
|
||||
|
||||
#### Example 4: Using Global and Local variables in same code
|
||||
```
|
||||
x = "global"
|
||||
|
||||
def foo():
|
||||
global x
|
||||
y = "local"
|
||||
x = x * 2
|
||||
print(x)
|
||||
print(y)
|
||||
|
||||
foo()
|
||||
|
||||
```
|
||||
|
||||
When we run the code, the will output be:
|
||||
```
|
||||
global global
|
||||
local
|
||||
|
||||
```
|
||||
|
||||
In the above code, we declare x as a global and y as a local variable in the `foo()`. Then, we use multiplication operator `*` to modify the global variable x and we print both x and y.
|
||||
|
||||
After calling the `foo()`, the value of x becomes `global global` because we used the `x * 2` to print two times `global`. After that, we print the value of local variable y i.e `local`.
|
||||
|
||||
#### Example 5: Global variable and Local variable with same name
|
||||
```
|
||||
x = 5
|
||||
|
||||
def foo():
|
||||
x = 10
|
||||
print("local x:", x)
|
||||
|
||||
foo()
|
||||
print("global x:", x)
|
||||
|
||||
```
|
||||
|
||||
When we run the code, the will output be:
|
||||
```
|
||||
local x: 10
|
||||
global x: 5
|
||||
|
||||
```
|
||||
|
||||
In above code, we used same name x for both global variable and local variable. We get different result when we print same variable because the variable is declared in both scopes, i.e. the local scope inside `foo()` and global scope outside `foo()`.
|
||||
|
||||
When we print the variable inside the `foo()` it outputs `local x: 10`, this is called local scope of variable.
|
||||
|
||||
Similarly, when we print the variable outside the `foo()`, it outputs `global x: 5`, this is called global scope of variable.
|
||||
|
||||
### Nonlocal Variables
|
||||
|
||||
Nonlocal variable are used in nested function whose local scope is not defined. This means, the variable can be neither in the local nor the global scope.
|
||||
|
||||
Let's see an example on how a global variable is created in Python.
|
||||
|
||||
We use `nonlocal` keyword to create nonlocal variable.
|
||||
|
||||
#### Example 6: Create a nonlocal variable
|
||||
```
|
||||
def outer():
|
||||
x = "local"
|
||||
|
||||
def inner():
|
||||
nonlocal x
|
||||
x = "nonlocal"
|
||||
print("inner:", x)
|
||||
|
||||
inner()
|
||||
print("outer:", x)
|
||||
|
||||
outer()
|
||||
|
||||
```
|
||||
|
||||
When we run the code, the will output be:
|
||||
```
|
||||
inner: nonlocal
|
||||
outer: nonlocal
|
||||
|
||||
```
|
||||
|
||||
In the above code there is a nested function `inner()`. We use `nonlocal` keyword to create nonlocal variable. The `inner()` function is defined in the scope of another function `outer()`.
|
||||
|
||||
Note : If we change value of nonlocal variable, the changes appears in the local variable.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.programiz.com/python-programming/global-local-nonlocal-variables
|
||||
|
||||
作者:[programiz][a]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://www.programiz.com/
|
||||
[1]:https://www.programiz.com/python-programming/global-keyword
|
@ -0,0 +1,255 @@
|
||||
A review of Virtual Labs virtualization solutions for MOOCs – WebLog Pro Olivier Berger
|
||||
======
|
||||
### 1 Introduction
|
||||
|
||||
This is a memo that tries to capture some of the experience gained in the [FLIRT project][3] on the topic of Virtual Labs for MOOCs (Massive Open Online Courses).
|
||||
|
||||
In this memo, we try to draw an overview of some benefits and concerns with existing approaches at using virtualization techniques for running Virtual Labs, as distributions of tools made available for distant learners.
|
||||
|
||||
We describe 3 main technical architectures: (1) running Virtual Machine images locally on a virtual machine manager, or (2) displaying the remote execution of similar virtual machines on a IaaS cloud, and (3) the potential of connecting to the remote execution of minimized containers on a remote PaaS cloud.
|
||||
|
||||
We then elaborate on some perspectives for locally running ports of applications to the WebAssembly virtual machine of the modern Web browsers.
|
||||
|
||||
Disclaimer: This memo doesn’t intend to point to extensive literature on the subject, so part of our analysis may be biased by our particular context.
|
||||
|
||||
### 2 Context : MOOCs
|
||||
|
||||
Many MOOCs (Massive Open Online Courses) include a kind of “virtual laboratory” for learners to experiment with tools, as a way to apply the knowledge, practice, and be more active in the learning process. In quite a few (technical) disciplines, this can consist in using a set of standard applications in a professional domain, which represent typical tools that would be used in real life scenarii.
|
||||
|
||||
Our main perspective will be that of a MOOC editor and of MOOC production teams which want to make “virtual labs” available for MOOC participants.
|
||||
|
||||
Such a “virtual lab” would typically contain installations of existing applications, pre-installed and configured, and loaded with scenario data in order to perform a lab.
|
||||
|
||||
The main constraint here is that such labs would typically be fabricated with limited software development expertise and funds[1][4]. Thus we consider here only the assembly of existing “normal” applications and discard the option of developping novel “serious games” and simulator applications for such MOOCs.
|
||||
|
||||
#### 2.1 The FLIRT project
|
||||
|
||||
The [FLIRT project][5] groups a consortium of 19 partners in Industry, SMEs and Academia to work on a collection of MOOCs and SPOCs for professional development in Networks and Telecommunications. Lead by Institut Mines Telecom, it benefits from the funding support of the French “Investissements d’avenir” programme.
|
||||
|
||||
As part of the FLIRT roadmap, we’re leading an “innovation task” focused on Virtual Labs in the context of the Cloud. This memo was produced as part of this task.
|
||||
|
||||
#### 2.2 Some challenges in virtual labs design for distant learning
|
||||
|
||||
Virtual Labs used in distance learning contexts require the use of software applications in autonomy, either running on a personal, or professional computer. In general, the technical skills of participants may be diverse. So much for the quality (bandwith, QoS, filtering, limitations: firewaling) of the hardware and networks they use at home or at work. It’s thus very optimistic to seek for one solution fits all strategy.
|
||||
|
||||
Most of the time there’s a learning curve on getting familiar with the tools which students will have to use, which constitutes as many challenges to overcome for beginners. These tools may not be suited for beginners, but they will still be selected by the trainers as they’re representative of the professional context being taught.
|
||||
|
||||
In theory, this usability challenge should be addressed by devising an adapted pedagogical approach, especially in a context of distance learning, so that learners can practice the labs on their own, without the presence of a tutor or professor. Or some particular prerequisite skills could be required (“please follow System Administration 101 before applying to this course”).
|
||||
|
||||
Unfortunately there are many cases where instructors basically just translate to a distant learning scenario, previous lab resources that had previously been devised for in presence learning. This lets learner faced with many challenges to overcome. The only support resource is often a regular forum on the MOOC’s LMS (Learning Management System).
|
||||
|
||||
My intuition[2][6] is that developing ad-hoc simulators for distant education would probably be more efficient and easy to use for learners. But that would require a too high investment for the designers of the courses.
|
||||
|
||||
In the context of MOOCs which are mainly free to participate to, not much investment is possible in devising ad-hoc lab applications, and instructors have to rely on existing applications, tools and scenarii to deliver a cheap enough environment. Furthermore, technical or licensing constraints[3][7] may lead to selecting lab tools which may not be easy to learn, but have the great advantage or being freely redistributable[4][8].
|
||||
|
||||
### 3 Virtual Machines for Virtual Labs
|
||||
|
||||
The learners who will try unattended learning in such typical virtual labs will face difficulties in making specialized applications run. They must overcome the technical details of downloading, installing and configuring programs, before even trying to perform a particular pedagogical scenario linked to the matter studied.
|
||||
|
||||
To diminish these difficulties, one traditional approach for implementing labs in MOOCs has been to assemble in advance a Virtual Machine image. This already made image can then be downloaded and run with a virtual machine simulator (like [VirtualBox][9][5][10]).
|
||||
|
||||
The pre-loaded VM will already have everything ready for use, so that the learners don’t have to install anything on their machines.
|
||||
|
||||
An alternative is to let learners download and install the needed software tools themselves, but this leads to so many compatibility issues or technical skill prerequisites, that this is often not advised, and mentioned only as a fallback option.
|
||||
|
||||
#### 3.1 Downloading and installation issues
|
||||
|
||||
Experience shows[2][11] that such virtual machines also bring some issues. Even if installation of every piece of software is no longer required, learners still need to be able to run the VM simulator on a wide range of diverse hardware, OSes and configurations. Even managing to download the VMs, still causes many issues (lack admin privileges, weight vs download speed, memory or CPU load, disk space, screen configurations, firewall filtering, keayboard layout, etc.).
|
||||
|
||||
These problems aren’t generally faced by the majority of learners, but the impacted minority is not marginal either, and they generally will produce a lot of support requests for the MOOC team (usually in the forums), which needs to be anticipated by the community managers.
|
||||
|
||||
The use of VMs is no show stopper for most, but can be a serious problem for a minority of learners, and is then no silver bullet.
|
||||
|
||||
Some general usability issues may also emerge if users aren’t used to the look and feel of the enclosed desktop. For instance, the VM may consist of a GNU/Linux desktop, whereas users would use a Windows or Mac OS system.
|
||||
|
||||
#### 3.2 Fabrication issues for the VM images
|
||||
|
||||
On the MOOC team’s side, the fabrication of a lightweight, fast, tested, license-free and easy to use VM image isn’t necessarily easy.
|
||||
|
||||
Software configurations tend to rot as time passes, and maintenance may not be easy when the later MOOC editions evolutions lead to the need to maintain the virtual lab scenarii years later.
|
||||
|
||||
Ideally, this would require adopting an “industrial” process in building (and testing) the lab VMs, but this requires quite an expertise (system administration, packaging, etc.) that may or not have been anticipated at the time of building the MOOC (unlike video editing competence, for instance).
|
||||
|
||||
Our experiment with the [Vagrant][12] technology [[0][13]] and Debian packaging was interesting in this respect, as it allowed us to use a well managed “script” to precisely control the build of a minimal VM image.
|
||||
|
||||
### 4 Virtual Labs as a Service
|
||||
|
||||
To overcome the difficulties in downloading and running Virtual Machines on one’s local computer, we have started exploring the possibility to run these applications in a kind of Software as a Service (SaaS) context, “on the cloud”.
|
||||
|
||||
But not all applications typically used in MOOC labs are already available for remote execution on the cloud (unless the course deals precisely with managing email in GMail).
|
||||
|
||||
We have then studied the option to use such an approach not for a single application, but for a whole virtual “desktop” which would be available on the cloud.
|
||||
|
||||
#### 4.1 IaaS deployments
|
||||
|
||||
A way to achieve this goal is to deploy Virtual Machine images quite similar to the ones described above, on the cloud, in an Infrastructure as a Service (IaaS) context[6][14], to offer access to remote desktops for every learners.
|
||||
|
||||
There are different technical options to achieve this goal, but a simplified description of the architecture can be seen as just running Virtual Machines on a single IaaS platform instead of on each learner’s computer. Access to the desktop and application interfaces is made possible with the use of Web pages (or other dedicated lightweight clients) which will display a “full screen” display of the remote desktop running for the user on the cloud VM. Under the hood, the remote display of a Linux desktop session is made with technologies like [VNC][15] and [RDP][16] connecting to a [Guacamole][17] server on the remote VM.
|
||||
|
||||
In the context of the FLIRT project, we have made early experiments with such an architecture. We used the CloVER solution by our partner [ProCAN][18] which provides a virtual desktops broker between [OpenEdX][19] and an [OpenStack][20] IaaS public platform.
|
||||
|
||||
The expected benefit is that users don’t have to install anything locally, as the only tool needed locally is a Web browser (displaying a full-screen [HTML5 canvas][21] displaying the remote desktop run by the Guacamole server running on the cloud VM.
|
||||
|
||||
But there are still some issues with such an approach. First, the cost of operating such an infrastructure : Virtual Machines need to be hosted on a IaaS platform, and that cost of operation isn’t null[7][22] for the MOOC editor, compared to the cost of VirtualBox and a VM running on the learner’s side (basically zero for the MOOC editor).
|
||||
|
||||
Another issue, which could be more problematic lies in the need for a reliable connection to the Internet during the whole sequences of lab execution by the learners[8][23]. Even if Guacamole is quite efficient at compressing rendering traffic, some basic connectivity is needed during the whole Lab work sessions, preventing some mobile uses for instance.
|
||||
|
||||
One other potential annoyance is the potential delays for making a VM available to a learner (provisioning a VM), when huge VMs images need to be copied inside the IaaS platform when a learner connects to the Virtual Lab activity for the first time (several minutes delays). This may be worse if the VM image is too big (hence the need for optimization of the content[9][24]).
|
||||
|
||||
However, the fact that all VMs are running on a platform under the control of the MOOC editor allows new kind of features for the MOOC. For instance, learners can submit results of their labs directly to the LMS without the need to upload or copy-paste results manually. This can help monitor progress or perform evaluation or grading.
|
||||
|
||||
The fact that their VMs run on the same platform also allows new kinds of pedagogical scenarii, as VMs of multiple learners can be interconnected, allowing cooperative activities between learners. The VM images may then need to be instrumented and deployed in particular configurations, which may require the use of a dedicated broker like CloVER to manage such scenarii.
|
||||
|
||||
For the records, we have yet to perform a rigorous benchmarking of such a solution in order to evaluate its benefits, or constraints given particular contexts. In FLIRT, our main focus will be in the context of SPOCs for professional training (a bit different a context than public MOOCs).
|
||||
|
||||
Still this approach doesn’t solve the VMs fabrication issues for the MOOC staff. Installing software inside a VM, be it local inside a VirtualBox simulator of over the cloud through a remote desktop display, makes not much difference. This relies mainly on manual operations and may not be well managed in terms of quality of the process (reproducibility, optimization).
|
||||
|
||||
#### 4.2 PaaS deployments using containers
|
||||
|
||||
Some key issues in the IaaS context described above, are the cost of operation of running full VMs, and long provisioning delays.
|
||||
|
||||
We’re experimenting with new options to address these issues, through the use of [Linux containers][25] running on a PaaS (Platform as a Service) platform, instead of full-fleshed Virtual Machines[10][26].
|
||||
|
||||
The main difference, with containers instead of Virtual Machines, lies in the reduced size of images, and much lower CPU load requirements, as the container remove the need for one layer of virtualization. Also, the deduplication techniques at the heart of some virtual file-systems used by container platforms lead to really fast provisioning, avoiding the need to wait for the labs to start.
|
||||
|
||||
The traditional making of VMs, done by installing packages and taking a snapshot, was affordable for the regular teacher, but involved manual operations. In this respect, one other major benefit of containers is the potential for better industrialization of the virtual lab fabrication, as they are generally not assembled manually. Instead, one uses a “scripting” approach in describing which applications and their dependencies need to be put inside a container image. But this requires new competence from the Lab creators, like learning the [Docker][27] technology (and the [OpenShift][28] PaaS, for instance), which may be quite specialized. Whereas Docker containers tend to become quite popular in Software Development faculty (through the “[devops][29]” hype), they may be a bit new to other field instructors.
|
||||
|
||||
The learning curve to mastering the automation of the whole container-based labs installation needs to be evaluated. There’s a trade-off to consider in adopting technology like Vagrant or Docker: acquiring container/PaaS expertise vs quality of industrialization and optimization. The production of a MOOC should then require careful planning if one has to hire or contract with a PaaS expert for setting up the Virtual Labs.
|
||||
|
||||
We may also expect interesting pedagogical benefits. As containers are lightweight, and platforms allow to “easily” deploy multiple interlinked containers (over dedicated virtual networks), this enables the setup of more realistic scenarii, where each learner may be provided with multiple “nodes” over virtual networks (all running their individual containers). This would be particularly interesting for Computer Networks or Security teaching for instance, where each learner may have access both to client and server nodes, to study client-server protocols, for instance. This is particularly interesting for us in the context of our FLIRT project, where we produce a collection of Computer Networks courses.
|
||||
|
||||
Still, this mode of operation relies on a good connectivity of the learners to the Cloud. In contexts of distance learning in poorly connected contexts, the PaaS architecture doesn’t solve that particular issue compared to the previous IaaS architecture.
|
||||
|
||||
### 5 Future server-less Virtual Labs with WebAssembly
|
||||
|
||||
As we have seen, the IaaS or PaaS based Virtual Labs running on the Cloud offer alternatives to installing local virtual machines on the learner’s computer. But they both require to be connected for the whole duration of the Lab, as the applications would be executed on the remote servers, on the Cloud (either inside VMs or containers).
|
||||
|
||||
We have been thinking of another alternative which could allow the deployment of some Virtual Labs on the local computers of the learners without the hassles of downloading and installing a Virtual Machine manager and VM image. We envision the possibility to use the infrastructure provided by modern Web browsers to allow running the lab’s applications.
|
||||
|
||||
At the time of writing, this architecture is still highly experimental. The main idea is to rebuild the applications needed for the Lab so that they can be run in the “generic” virtual machine present in the modern browsers, the [WebAssembly][30] and Javascript execution engine.
|
||||
|
||||
WebAssembly is a modern language which seeks for maximum portability, and as its name hints, is a kind of assembly language for the Web platform. What is of interest for us is that WebAssembly is portable on most modern Web browsers, making it a very interesting platform for portability.
|
||||
|
||||
Emerging toolchains allow recompiling applications written in languages like C or C++ so that they can be run on the WebAssembly virtual machine in the browser. This is interesting as it doesn’t require modifying the source code of these programs. Of course, there are limitations, in the kind of underlying APIs and libraries compatible with that platform, and on the sandboxing of the WebAssembly execution engine enforced by the Web browser.
|
||||
|
||||
Historically, WebAssembly has been developped so as to allow running games written in C++ for a framework like Unity, in the Web browser.
|
||||
|
||||
In some contexts, for instance for tools with an interactive GUI, and processing data retrieved from files, and which don’t need very specific interaction with the underlying operating system, it seems possible to port these programs to WebAssembly for running them inside the Web browser.
|
||||
|
||||
We have to experiment deeper with this technology to validate its potential for running Virtual Labs in the context of a Web browser.
|
||||
|
||||
We used a similar approach in the past in porting a Relational Database course lab to the Web browser, for standalone execution. A real database would run in the minimal SQLite RDBMS, recompiled to JavaScript[11][31]. Instead of having to download, install and run a VM with a RDBMS, the students would only connect to a Web page, which would load the DBMS in memory, and allow performing the lab SQL queries locally, disconnected from any third party server.
|
||||
|
||||
In a similar manner, we can think for instance, of a Lab scenario where the Internet packet inspector features of the Wireshark tool would run inside the WebAssembly virtual machine, to allow dissecting provided capture files, without having to install Wireshard, directly into the Web browser.
|
||||
|
||||
We expect to publish a report on that last experiment in the future with more details and results.
|
||||
|
||||
### 6 Conclusion
|
||||
|
||||
The most promising architecture for Virtual Lab deployments seems to be the use of containers on a PaaS platform for deploying virtual desktops or virtual application GUIs available in the Web browser.
|
||||
|
||||
This would allow the controlled fabrication of Virtual Labs containing the exact bits needed for learners to practice while minimizing the delays.
|
||||
|
||||
Still the need for always-on connectivity can be a problem.
|
||||
|
||||
Also, the potential for inter-networked containers allowing the kind of multiple nodes and collaborative scenarii we described, would require a lot of expertise to develop, and management platforms for the MOOC operators, which aren’t yet mature.
|
||||
|
||||
We hope to be able to report on our progress in the coming months and years on those aspects.
|
||||
|
||||
### 7 References
|
||||
|
||||
|
||||
|
||||
[0]
|
||||
Olivier Berger, J Paul Gibson, Claire Lecocq and Christian Bac “Designing a virtual laboratory for a relational database MOOC”. International Conference on Computer Supported Education, SCITEPRESS, 23-25 may 2015, Lisbonne, Portugal, 2015, vol. 7, pp. 260-268, ISBN 978-989-758-107-6 – [DOI: 10.5220/0005439702600268][1] ([preprint (HTML)][2])
|
||||
|
||||
### 8 Copyright
|
||||
|
||||
[![Creative Commons License](https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png)][45]
|
||||
|
||||
This work is licensed under a [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License][46]
|
||||
|
||||
.
|
||||
|
||||
### Footnotes:
|
||||
|
||||
[1][32] – The FLIRT project also works on business model aspects of MOOC or SPOC production in the context of professional development, but the present memo starts from a minimalitic hypothesis where funding for course production is quite limited.
|
||||
|
||||
[2][33] – research-based evidence needed
|
||||
|
||||
[3][34] – In typical MOOCs which are free to participate, the VM should include only gratis tools, which typically means a GNU/Linux distribution loaded with applications available under free and open source licenses.
|
||||
|
||||
[4][35] – Typically, Free and Open Source software, aka Libre Software
|
||||
|
||||
[5][36] – VirtualBox is portable on many operating systems, making it a very popular solution for such a need
|
||||
|
||||
[6][37] – the IaaS platform could typically be an open cloud for MOOCs or a private cloud for SPOCs (for closer monitoring of student activity or security control reasons).
|
||||
|
||||
[7][38] – Depending of the expected use of the lab by learners, this cost may vary a lot. The size and configuration required for the included software may have an impact (hence the need to minimize the footprint of the VM images). With diminishing costs in general this may not be a show stopper. Refer to marketing figures of commercial IaaS offerings for accurate figures. Attention to additional licensing costs if the OS of the VM isn’t free software, or if other licenses must be provided for every learners.
|
||||
|
||||
[8][39] – The needs for always-on connectivity may not be a problem for professional development SPOCs where learners connect from enterprise networks for instance. It may be detrimental when MOOCs are very popular in southern countries where high bandwidth is both unreliable and expensive.
|
||||
|
||||
[9][40] – In this respect, providing a full Linux desktop inside the VM doesn’t necessarily make sense. Instead, running applications full-screen may be better, avoiding installation of whole desktop environments like Gnome or XFCE… but which has usability consequences. Careful tuning and testing is needed in any case.
|
||||
|
||||
[10][41] – The availability of container based architectures is quite popular in the industry, but has not yet been deployed to a large scale in the context of large public MOOC hosting platforms, to our knowledge, at the time of writing. There are interesting technical challenges which the FLIRT project tries to tackle together with its partner ProCAN.
|
||||
|
||||
[11][42] – See the corresponding paragraph [http://www-inf.it-sudparis.eu/PROSE/csedu2015/#standalone-sql-env][43] in [0][44]
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www-public.tem-tsp.eu/~berger_o/weblog/a-review-of-virtual-labs-virtualization-solutions-for-moocs/
|
||||
|
||||
作者:[Author;Olivier Berger;Télécom Sudparis][a]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://www-public.tem-tsp.eu
|
||||
[1]:http://dx.doi.org/10.5220/0005439702600268
|
||||
[2]:http://www-inf.it-sudparis.eu/PROSE/csedu2015/
|
||||
[3]:https://www-public.tem-tsp.eu/~berger_o/weblog/a-review-of-virtual-labs-virtualization-solutions-for-moocs/#org50fdc1a
|
||||
[4]:https://www-public.tem-tsp.eu/~berger_o/weblog/a-review-of-virtual-labs-virtualization-solutions-for-moocs/#fn.1
|
||||
[5]:http://flirtmooc.wixsite.com/flirt-mooc-telecom
|
||||
[6]:https://www-public.tem-tsp.eu/~berger_o/weblog/a-review-of-virtual-labs-virtualization-solutions-for-moocs/#fn.2
|
||||
[7]:https://www-public.tem-tsp.eu/~berger_o/weblog/a-review-of-virtual-labs-virtualization-solutions-for-moocs/#fn.3
|
||||
[8]:https://www-public.tem-tsp.eu/~berger_o/weblog/a-review-of-virtual-labs-virtualization-solutions-for-moocs/#fn.4
|
||||
[9]:http://virtualbox.org
|
||||
[10]:https://www-public.tem-tsp.eu/~berger_o/weblog/a-review-of-virtual-labs-virtualization-solutions-for-moocs/#fn.5
|
||||
[11]:https://www-public.tem-tsp.eu/~berger_o/weblog/a-review-of-virtual-labs-virtualization-solutions-for-moocs/#fn.2
|
||||
[12]:https://www.vagrantup.com/
|
||||
[13]:https://www-public.tem-tsp.eu/~berger_o/weblog/a-review-of-virtual-labs-virtualization-solutions-for-moocs/#orgde5af50
|
||||
[14]:https://www-public.tem-tsp.eu/~berger_o/weblog/a-review-of-virtual-labs-virtualization-solutions-for-moocs/#fn.6
|
||||
[15]:https://en.wikipedia.org/wiki/Virtual_Network_Computing
|
||||
[16]:https://en.wikipedia.org/wiki/Remote_Desktop_Protocol
|
||||
[17]:http://guacamole.apache.org/
|
||||
[18]:https://www.procan-group.com/
|
||||
[19]:https://open.edx.org/
|
||||
[20]:http://openstack.org/
|
||||
[21]:https://en.wikipedia.org/wiki/Canvas_element
|
||||
[22]:https://www-public.tem-tsp.eu/~berger_o/weblog/a-review-of-virtual-labs-virtualization-solutions-for-moocs/#fn.7
|
||||
[23]:https://www-public.tem-tsp.eu/~berger_o/weblog/a-review-of-virtual-labs-virtualization-solutions-for-moocs/#fn.8
|
||||
[24]:https://www-public.tem-tsp.eu/~berger_o/weblog/a-review-of-virtual-labs-virtualization-solutions-for-moocs/#fn.9
|
||||
[25]:https://www.redhat.com/en/topics/containers
|
||||
[26]:https://www-public.tem-tsp.eu/~berger_o/weblog/a-review-of-virtual-labs-virtualization-solutions-for-moocs/#fn.10
|
||||
[27]:https://en.wikipedia.org/wiki/Docker_(software)
|
||||
[28]:https://www.openshift.com/
|
||||
[29]:https://en.wikipedia.org/wiki/DevOps
|
||||
[30]:http://webassembly.org/
|
||||
[31]:https://www-public.tem-tsp.eu/~berger_o/weblog/a-review-of-virtual-labs-virtualization-solutions-for-moocs/#fn.11
|
||||
[32]:https://www-public.tem-tsp.eu/~berger_o/weblog/a-review-of-virtual-labs-virtualization-solutions-for-moocs/#fnr.1
|
||||
[33]:https://www-public.tem-tsp.eu/~berger_o/weblog/a-review-of-virtual-labs-virtualization-solutions-for-moocs/#fnr.2
|
||||
[34]:https://www-public.tem-tsp.eu/~berger_o/weblog/a-review-of-virtual-labs-virtualization-solutions-for-moocs/#fnr.3
|
||||
[35]:https://www-public.tem-tsp.eu/~berger_o/weblog/a-review-of-virtual-labs-virtualization-solutions-for-moocs/#fnr.4
|
||||
[36]:https://www-public.tem-tsp.eu/~berger_o/weblog/a-review-of-virtual-labs-virtualization-solutions-for-moocs/#fnr.5
|
||||
[37]:https://www-public.tem-tsp.eu/~berger_o/weblog/a-review-of-virtual-labs-virtualization-solutions-for-moocs/#fnr.6
|
||||
[38]:https://www-public.tem-tsp.eu/~berger_o/weblog/a-review-of-virtual-labs-virtualization-solutions-for-moocs/#fnr.7
|
||||
[39]:https://www-public.tem-tsp.eu/~berger_o/weblog/a-review-of-virtual-labs-virtualization-solutions-for-moocs/#fnr.8
|
||||
[40]:https://www-public.tem-tsp.eu/~berger_o/weblog/a-review-of-virtual-labs-virtualization-solutions-for-moocs/#fnr.9
|
||||
[41]:https://www-public.tem-tsp.eu/~berger_o/weblog/a-review-of-virtual-labs-virtualization-solutions-for-moocs/#fnr.10
|
||||
[42]:https://www-public.tem-tsp.eu/~berger_o/weblog/a-review-of-virtual-labs-virtualization-solutions-for-moocs/#fnr.11
|
||||
[43]:http://www-inf.it-sudparis.eu/PROSE/csedu2015/#standalone-sql-env
|
||||
[44]:https://www-public.tem-tsp.eu/~berger_o/weblog/a-review-of-virtual-labs-virtualization-solutions-for-moocs/#orgde5af50
|
||||
[45]:http://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
[46]:http://creativecommons.org/licenses/by-nc-sa/4.0/
|
@ -0,0 +1,439 @@
|
||||
How to Install Gogs Go Git Service on Ubuntu 16.04
|
||||
======
|
||||
|
||||
Gogs is free and open source Git service written in Go language. Gogs is a painless self-hosted git service that allows you to create and run your own Git server on a minimal hardware server. Gogs web-UI is very similar to GitHub and offers support for MySQL, PostgreSQL, and SQLite database.
|
||||
|
||||
In this tutorial, we will show you step-by-step how to install and configure your own Git service using Gogs on Ubuntu 16.04. This tutorial will cover details including, how to install Go on Ubuntu system, install PostgreSQL, and install and configure Nginx web server as a reverse proxy for Go application.
|
||||
|
||||
### Prerequisites
|
||||
|
||||
* Ubuntu 16.04
|
||||
* Root privileges
|
||||
|
||||
|
||||
|
||||
### What we will do
|
||||
|
||||
1. Update and Upgrade System
|
||||
2. Install and Configure PostgreSQL
|
||||
3. Install Go and Git
|
||||
4. Install Gogs
|
||||
5. Configure Gogs
|
||||
6. Running Gogs as a Service
|
||||
7. Install and Configure Nginx as a Reverse Proxy
|
||||
8. Testing
|
||||
|
||||
|
||||
|
||||
Before going any further, update all Ubuntu repositories and upgrade all packages.
|
||||
|
||||
Run the apt commands below.
|
||||
|
||||
```
|
||||
sudo apt update
|
||||
sudo apt upgrade
|
||||
```
|
||||
|
||||
### Step 2 - Install and Configure PostgreSQL
|
||||
|
||||
Gogs offers support for MySQL, PostgreSQL, SQLite3, MSSQL, and TiDB database systems.
|
||||
|
||||
In this guide, we will be using PostgreSQL as a database for our Gogs installations.
|
||||
|
||||
Install PostgreSQL using the apt command below.
|
||||
|
||||
```
|
||||
sudo apt install -y postgresql postgresql-client libpq-dev
|
||||
```
|
||||
|
||||
After the installation is complete, start the PostgreSQL service and enable it to launch everytime at system boot.
|
||||
|
||||
```
|
||||
systemctl start postgresql
|
||||
systemctl enable postgresql
|
||||
```
|
||||
|
||||
PostgreSQL database has been installed on an Ubuntu system.
|
||||
|
||||
Next, we need to create a new database and user for Gogs.
|
||||
|
||||
Login as the 'postgres' user and run the 'psql' command to get the PostgreSQL shell.
|
||||
|
||||
```
|
||||
su - postgres
|
||||
psql
|
||||
```
|
||||
|
||||
Create a new user named 'git', and give the user privileges for 'CREATEDB'.
|
||||
|
||||
```
|
||||
CREATE USER git CREATEDB;
|
||||
\password git
|
||||
```
|
||||
|
||||
Create a database named 'gogs_production', and set the 'git' user as the owner of the database.
|
||||
|
||||
```
|
||||
CREATE DATABASE gogs_production OWNER git;
|
||||
```
|
||||
|
||||
[![Create the Gogs database][1]][2]
|
||||
|
||||
New PostgreSQL database 'gogs_production' and user 'git' for Gogs installation has been created.
|
||||
|
||||
### Step 3 - Install Go and Git
|
||||
|
||||
Install Git from the repository using the apt command below.
|
||||
|
||||
```
|
||||
sudo apt install git
|
||||
```
|
||||
|
||||
Now add new user 'git' to the system.
|
||||
|
||||
```
|
||||
sudo adduser --disabled-login --gecos 'Gogs' git
|
||||
```
|
||||
|
||||
Login as the 'git' user and create a new 'local' directory.
|
||||
|
||||
```
|
||||
su - git
|
||||
mkdir -p /home/git/local
|
||||
```
|
||||
|
||||
Go to the 'local' directory and download 'Go' (the latest version) using the wget command as shown below.
|
||||
|
||||
```
|
||||
cd ~/local
|
||||
wget <https://dl.google.com/go/go1.9.2.linux-amd64.tar.gz>
|
||||
```
|
||||
|
||||
[![Install Go and Git][3]][4]
|
||||
|
||||
Extract the go compressed file, then remove it.
|
||||
|
||||
```
|
||||
tar -xf go1.9.2.linux-amd64.tar.gz
|
||||
rm -f go1.9.2.linux-amd64.tar.gz
|
||||
```
|
||||
|
||||
'Go' binary file has been downloaded in the '~/local/go' directory. Now we need to setup the environment - we need to define the 'GOROOT' and 'GOPATH directories so we can run a 'go' command on the system under 'git' user.
|
||||
|
||||
Run all of the following commands.
|
||||
|
||||
```
|
||||
cd ~/
|
||||
echo 'export GOROOT=$HOME/local/go' >> $HOME/.bashrc
|
||||
echo 'export GOPATH=$HOME/go' >> $HOME/.bashrc
|
||||
echo 'export PATH=$PATH:$GOROOT/bin:$GOPATH/bin' >> $HOME/.bashrc
|
||||
```
|
||||
|
||||
And reload Bash by running the 'source ~/.bashrc' command as shown below.
|
||||
|
||||
```
|
||||
source ~/.bashrc
|
||||
```
|
||||
|
||||
Make sure you're using Bash as your default shell.
|
||||
|
||||
[![Install Go programming language][5]][6]
|
||||
|
||||
Now run the 'go' command for checking the version.
|
||||
|
||||
```
|
||||
go version
|
||||
```
|
||||
|
||||
And make sure you get the result as shown in the following screenshot.
|
||||
|
||||
[![Check the go version][7]][8]
|
||||
|
||||
Go is now installed on the system under 'git' user.
|
||||
|
||||
### Step 4 - Install Gogs Go Git Service
|
||||
|
||||
Login as the 'git' user and download 'Gogs' from GitHub using the 'go' command.
|
||||
|
||||
```
|
||||
su - git
|
||||
go get -u github.com/gogits/gogs
|
||||
```
|
||||
|
||||
The command will download all Gogs source code in the 'GOPATH/src' directory.
|
||||
|
||||
Go to the '$GOPATH/src/github.com/gogits/gogs' directory and build gogs using commands below.
|
||||
|
||||
```
|
||||
cd $GOPATH/src/github.com/gogits/gogs
|
||||
go build
|
||||
```
|
||||
|
||||
And make sure you get no error.
|
||||
|
||||
Now run Gogs Go Git Service using the command below.
|
||||
|
||||
```
|
||||
./gogs web
|
||||
```
|
||||
|
||||
The command will run Gogs on the default port 3000.
|
||||
|
||||
[![Install Gogs Go Git Service][9]][10]
|
||||
|
||||
Open your web browser and type your server IP address with port 3000, mine is <http://192.168.33.10:3000/>
|
||||
|
||||
And you should get the result as shown below.
|
||||
|
||||
[![Gogs web installer][11]][12]
|
||||
|
||||
Gogs is installed on the Ubuntu system. Now back to your terminal and press 'Ctrl + c' to exit.
|
||||
|
||||
### Step 5 - Configure Gogs Go Git Service
|
||||
|
||||
In this step, we will create a custom configuration for Gogs.
|
||||
|
||||
Goto the Gogs installation directory and create a new 'custom/conf' directory.
|
||||
|
||||
```
|
||||
cd $GOPATH/src/github.com/gogits/gogs
|
||||
mkdir -p custom/conf/
|
||||
```
|
||||
|
||||
Copy default configuration to the custom directory and edit it using [vim][13].
|
||||
|
||||
```
|
||||
cp conf/app.ini custom/conf/app.ini
|
||||
vim custom/conf/app.ini
|
||||
```
|
||||
|
||||
In the ' **[server]** ' section, change the server 'HOST_ADDR' with '127.0.0.1'.
|
||||
```
|
||||
[server]
|
||||
PROTOCOL = http
|
||||
DOMAIN = localhost
|
||||
ROOT_URL = %(PROTOCOL)s://%(DOMAIN)s:%(HTTP_PORT)s/
|
||||
HTTP_ADDR = 127.0.0.1
|
||||
HTTP_PORT = 3000
|
||||
|
||||
```
|
||||
|
||||
In the ' **[database]** ' section, change everything with your own database info.
|
||||
```
|
||||
[database]
|
||||
DB_TYPE = postgres
|
||||
HOST = 127.0.0.1:5432
|
||||
NAME = gogs_production
|
||||
USER = git
|
||||
PASSWD = [email protected]#
|
||||
|
||||
```
|
||||
|
||||
Save and exit.
|
||||
|
||||
Now verify the configuration by running the command as shown below.
|
||||
|
||||
```
|
||||
./gogs web
|
||||
```
|
||||
|
||||
And make sure you get the result as following.
|
||||
|
||||
[![Configure the service][14]][15]
|
||||
|
||||
Gogs is now running with our custom configuration, under 'localhost' with port 3000.
|
||||
|
||||
### Step 6 - Running Gogs as a Service
|
||||
|
||||
In this step, we will configure Gogs as a service on Ubuntu system. We will create a new service file configuration 'gogs.service' under the '/etc/systemd/system' directory.
|
||||
|
||||
Go to the '/etc/systemd/system' directory and create a new service file 'gogs.service' using the [vim][13] editor.
|
||||
|
||||
```
|
||||
cd /etc/systemd/system
|
||||
vim gogs.service
|
||||
```
|
||||
|
||||
Paste the following gogs service configuration there.
|
||||
```
|
||||
[Unit]
|
||||
Description=Gogs
|
||||
After=syslog.target
|
||||
After=network.target
|
||||
After=mariadb.service mysqld.service postgresql.service memcached.service redis.service
|
||||
|
||||
[Service]
|
||||
# Modify these two values and uncomment them if you have
|
||||
# repos with lots of files and get an HTTP error 500 because
|
||||
# of that
|
||||
###
|
||||
#LimitMEMLOCK=infinity
|
||||
#LimitNOFILE=65535
|
||||
Type=simple
|
||||
User=git
|
||||
Group=git
|
||||
WorkingDirectory=/home/git/go/src/github.com/gogits/gogs
|
||||
ExecStart=/home/git/go/src/github.com/gogits/gogs/gogs web
|
||||
Restart=always
|
||||
Environment=USER=git HOME=/home/git
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
```
|
||||
|
||||
Save and exit.
|
||||
|
||||
Now reload the systemd services.
|
||||
|
||||
```
|
||||
systemctl daemon-reload
|
||||
```
|
||||
|
||||
Start gogs service and enable it to launch everytime at system boot using the systemctl command.
|
||||
|
||||
```
|
||||
systemctl start gogs
|
||||
systemctl enable gogs
|
||||
```
|
||||
|
||||
[![Run gogs as a service][16]][17]
|
||||
|
||||
Gogs is now running as a service on Ubuntu system.
|
||||
|
||||
Check it using the commands below.
|
||||
|
||||
```
|
||||
netstat -plntu
|
||||
systemctl status gogs
|
||||
```
|
||||
|
||||
And you should get the result as shown below.
|
||||
|
||||
[![Gogs is listening on the network interface][18]][19]
|
||||
|
||||
### Step 7 - Configure Nginx as a Reverse Proxy for Gogs
|
||||
|
||||
In this step, we will configure Nginx as a reverse proxy for Gogs. We will be using Nginx packages from its own repository.
|
||||
|
||||
Add Nginx repository using the add-apt command.
|
||||
|
||||
```
|
||||
sudo add-apt-repository -y ppa:nginx/stable
|
||||
```
|
||||
|
||||
Now update all Ubuntu repositories and install Nginx using the apt command below.
|
||||
|
||||
```
|
||||
sudo apt update
|
||||
sudo apt install nginx -y
|
||||
```
|
||||
|
||||
Next, goto the '/etc/nginx/sites-available' directory and create new virtual host file 'gogs'.
|
||||
|
||||
```
|
||||
cd /etc/nginx/sites-available
|
||||
vim gogs
|
||||
```
|
||||
|
||||
Paste the following configuration there.
|
||||
```
|
||||
server {
|
||||
listen 80;
|
||||
server_name git.hakase-labs.co;
|
||||
|
||||
location / {
|
||||
proxy_pass http://localhost:3000;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Save and exit.
|
||||
|
||||
**Note:**
|
||||
|
||||
Change the 'server_name' line with your own domain name.
|
||||
|
||||
Now activate a new virtual host and test the nginx configuration.
|
||||
|
||||
```
|
||||
ln -s /etc/nginx/sites-available/gogs /etc/nginx/sites-enabled/
|
||||
nginx -t
|
||||
```
|
||||
|
||||
Make sure there is no error, then restart the Nginx service.
|
||||
|
||||
```
|
||||
systemctl restart nginx
|
||||
```
|
||||
|
||||
[![Nginx reverse proxy for gogs][20]][21]
|
||||
|
||||
### Step 8 - Testing
|
||||
|
||||
Open your web browser and type your gogs URL, mine is <http://git.hakase-labs.co>
|
||||
|
||||
Now you will get the installation page. On top of the page, type all of your PostgreSQL database info.
|
||||
|
||||
[![Gogs installer][22]][23]
|
||||
|
||||
Now scroll to the bottom, and click the 'Admin account settings' dropdown.
|
||||
|
||||
Type your admin user, password, and email.
|
||||
|
||||
[![Type in the gogs install settings][24]][25]
|
||||
|
||||
Then click the 'Install Gogs' button.
|
||||
|
||||
And you will be redirected to the Gogs user Dashboard as shown below.
|
||||
|
||||
[![Gogs dashboard][26]][27]
|
||||
|
||||
Below is Gogs 'Admin Dashboard'.
|
||||
|
||||
[![Browse the Gogs dashboard][28]][29]
|
||||
|
||||
Gogs is now installed with PostgreSQL database and Nginx web server on Ubuntu 16.04 server
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.howtoforge.com/tutorial/how-to-install-gogs-go-git-service-on-ubuntu-1604/
|
||||
|
||||
作者:[Muhammad Arul][a]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.howtoforge.com/tutorial/server-monitoring-with-shinken-on-ubuntu-16-04/
|
||||
[1]:https://www.howtoforge.com/images/how_to_install_gogs_go_git_service_on_ubuntu_1604/1.png
|
||||
[2]:https://www.howtoforge.com/images/how_to_install_gogs_go_git_service_on_ubuntu_1604/big/1.png
|
||||
[3]:https://www.howtoforge.com/images/how_to_install_gogs_go_git_service_on_ubuntu_1604/2.png
|
||||
[4]:https://www.howtoforge.com/images/how_to_install_gogs_go_git_service_on_ubuntu_1604/big/2.png
|
||||
[5]:https://www.howtoforge.com/images/how_to_install_gogs_go_git_service_on_ubuntu_1604/3.png
|
||||
[6]:https://www.howtoforge.com/images/how_to_install_gogs_go_git_service_on_ubuntu_1604/big/3.png
|
||||
[7]:https://www.howtoforge.com/images/how_to_install_gogs_go_git_service_on_ubuntu_1604/4.png
|
||||
[8]:https://www.howtoforge.com/images/how_to_install_gogs_go_git_service_on_ubuntu_1604/big/4.png
|
||||
[9]:https://www.howtoforge.com/images/how_to_install_gogs_go_git_service_on_ubuntu_1604/5.png
|
||||
[10]:https://www.howtoforge.com/images/how_to_install_gogs_go_git_service_on_ubuntu_1604/big/5.png
|
||||
[11]:https://www.howtoforge.com/images/how_to_install_gogs_go_git_service_on_ubuntu_1604/6.png
|
||||
[12]:https://www.howtoforge.com/images/how_to_install_gogs_go_git_service_on_ubuntu_1604/big/6.png
|
||||
[13]:https://www.howtoforge.com/vim-basics
|
||||
[14]:https://www.howtoforge.com/images/how_to_install_gogs_go_git_service_on_ubuntu_1604/7.png
|
||||
[15]:https://www.howtoforge.com/images/how_to_install_gogs_go_git_service_on_ubuntu_1604/big/7.png
|
||||
[16]:https://www.howtoforge.com/images/how_to_install_gogs_go_git_service_on_ubuntu_1604/8.png
|
||||
[17]:https://www.howtoforge.com/images/how_to_install_gogs_go_git_service_on_ubuntu_1604/big/8.png
|
||||
[18]:https://www.howtoforge.com/images/how_to_install_gogs_go_git_service_on_ubuntu_1604/9.png
|
||||
[19]:https://www.howtoforge.com/images/how_to_install_gogs_go_git_service_on_ubuntu_1604/big/9.png
|
||||
[20]:https://www.howtoforge.com/images/how_to_install_gogs_go_git_service_on_ubuntu_1604/10.png
|
||||
[21]:https://www.howtoforge.com/images/how_to_install_gogs_go_git_service_on_ubuntu_1604/big/10.png
|
||||
[22]:https://www.howtoforge.com/images/how_to_install_gogs_go_git_service_on_ubuntu_1604/11.png
|
||||
[23]:https://www.howtoforge.com/images/how_to_install_gogs_go_git_service_on_ubuntu_1604/big/11.png
|
||||
[24]:https://www.howtoforge.com/images/how_to_install_gogs_go_git_service_on_ubuntu_1604/12.png
|
||||
[25]:https://www.howtoforge.com/images/how_to_install_gogs_go_git_service_on_ubuntu_1604/big/12.png
|
||||
[26]:https://www.howtoforge.com/images/how_to_install_gogs_go_git_service_on_ubuntu_1604/13.png
|
||||
[27]:https://www.howtoforge.com/images/how_to_install_gogs_go_git_service_on_ubuntu_1604/big/13.png
|
||||
[28]:https://www.howtoforge.com/images/how_to_install_gogs_go_git_service_on_ubuntu_1604/14.png
|
||||
[29]:https://www.howtoforge.com/images/how_to_install_gogs_go_git_service_on_ubuntu_1604/big/14.png
|
@ -0,0 +1,121 @@
|
||||
How to setup and configure network bridge on Debian Linux
|
||||
======
|
||||
|
||||
I am new Debian Linux user. I want to setup Bridge for virtualised environments (KVM) running on Debian Linux. How do I setup network bridging in /etc/network/interfaces on Debian Linux 9.x server?
|
||||
|
||||
If you want to assign IP addresses to your virtual machines and make them accessible from your LAN you need to setup network bridge. By default, a private network bridge created when using KVM. You need to set up interfaces manually, avoiding conflicts with, network manager.
|
||||
|
||||
### How to install the brctl
|
||||
|
||||
Type the following [nixcmdn name=”apt”]/[apt-get command][1]:
|
||||
`$ sudo apt install bridge-utils`
|
||||
|
||||
### How to setup network bridge on Debian Linux
|
||||
|
||||
You need to edit /etc/network/interface file. However, I recommend to drop a brand new config in /etc/network/interface.d/ directory. The procedure to configure network bridge on Debian Linux is as follows:
|
||||
|
||||
#### Step 1 – Find out your physical interface
|
||||
|
||||
Use the [ip command][2]:
|
||||
`$ ip -f inet a s`
|
||||
Sample outputs:
|
||||
```
|
||||
2: eno1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
|
||||
inet 192.168.2.23/24 brd 192.168.2.255 scope global eno1
|
||||
valid_lft forever preferred_lft forever
|
||||
```
|
||||
|
||||
|
||||
eno1 is my physical interface.
|
||||
|
||||
#### Step 2 – Update /etc/network/interface file
|
||||
|
||||
Make sure only lo (loopback is active in /etc/network/interface). Remove any config related to eno1. Here is my config file printed using [cat command][3]:
|
||||
`$ cat /etc/network/interface`
|
||||
```
|
||||
# This file describes the network interfaces available on your system
|
||||
# and how to activate them. For more information, see interfaces(5).
|
||||
|
||||
source /etc/network/interfaces.d/*
|
||||
|
||||
# The loopback network interface
|
||||
auto lo
|
||||
iface lo inet loopback
|
||||
```
|
||||
|
||||
|
||||
#### Step 3 – Configuring bridging (br0) in /etc/network/interfaces.d/br0
|
||||
|
||||
Create a text file using a text editor such as vi command:
|
||||
`$ sudo vi /etc/network/interfaces.d/br0`
|
||||
Append the following config:
|
||||
```
|
||||
## static ip config file for br0 ##
|
||||
auto br0
|
||||
iface br0 inet static
|
||||
address 192.168.2.23
|
||||
broadcast 192.168.2.255
|
||||
netmask 255.255.255.0
|
||||
gateway 192.168.2.254
|
||||
# If the resolvconf package is installed, you should not edit
|
||||
# the resolv.conf configuration file manually. Set name server here
|
||||
#dns-nameservers 192.168.2.254
|
||||
# If you have muliple interfaces such as eth0 and eth1
|
||||
# bridge_ports eth0 eth1
|
||||
bridge_ports eno1
|
||||
bridge_stp off # disable Spanning Tree Protocol
|
||||
bridge_waitport 0 # no delay before a port becomes available
|
||||
bridge_fd 0 # no forwarding delay
|
||||
```
|
||||
|
||||
If you want bridge to get an IP address using DHCP:
|
||||
```
|
||||
## DHCP ip config file for br0 ##
|
||||
auto br0
|
||||
|
||||
# Bridge setup
|
||||
iface br0 inet dhcp
|
||||
bridge_ports eno1
|
||||
```
|
||||
|
||||
|
||||
[Save and close the file in vi/vim][4].
|
||||
|
||||
#### Step 4 – [Restart networking service in Linux][5]
|
||||
|
||||
Before you restart the networking service make sure firewall is disabled. The firewall may refer to older interface such as eno1. Once service restarted, you must update firewall rule for interface br0. Type the following restart the networking service:
|
||||
`$ sudo systemctl restart network-manager`
|
||||
Verify that service has been restarted:
|
||||
`$ systemctl status network-manager`
|
||||
Look for new br0 interface and routing table with the help of [ip command][2]:
|
||||
`$ ip a s $ ip r $ ping -c 2 cyberciti.biz`
|
||||
Sample outputs:
|
||||
![](https://www.cyberciti.biz/media/new/faq/2018/02/How-to-setup-and-configure-network-bridge-on-Debian-Linux.jpg)
|
||||
You can also use the brctl command to view info about your bridges:
|
||||
`$ brctl show`
|
||||
Show current bridges:
|
||||
`$ bridge link`
|
||||
![](https://www.cyberciti.biz/media/new/faq/2018/02/Show-current-bridges-and-what-interfaces-they-are-connected-to-on-Linux.jpg)
|
||||
|
||||
### About the author
|
||||
|
||||
The author is the creator of nixCraft and a seasoned sysadmin, DevOps engineer, and a trainer for the Linux operating system/Unix shell scripting. Get the **latest tutorials on SysAdmin, Linux/Unix and open source topics via[RSS/XML feed][6]** or [weekly email newsletter][7].
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.cyberciti.biz/faq/how-to-configuring-bridging-in-debian-linux/
|
||||
|
||||
作者:[Vivek GIte][a]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://www.cyberciti.biz/
|
||||
[1]:https://www.cyberciti.biz/tips/linux-debian-package-management-cheat-sheet.html (See Linux/Unix apt-get command examples for more info)
|
||||
[2]:https://www.cyberciti.biz/faq/linux-ip-command-examples-usage-syntax/ (See Linux/Unix ip command examples for more info)
|
||||
[3]:https://www.cyberciti.biz/faq/linux-unix-appleosx-bsd-cat-command-examples/ (See Linux/Unix cat command examples for more info)
|
||||
[4]:https://www.cyberciti.biz/faq/linux-unix-vim-save-and-quit-command/
|
||||
[5]:https://www.cyberciti.biz/faq/linux-restart-network-interface/
|
||||
[6]:https://www.cyberciti.biz/atom/atom.xml
|
||||
[7]:https://www.cyberciti.biz/subscribe-to-weekly-linux-unix-newsletter-for-sysadmin/
|
@ -0,0 +1,299 @@
|
||||
How to use Twine and SugarCube to create interactive adventure games
|
||||
======
|
||||
|
||||
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/open_gaming_games_roundup_news.png?itok=KM0ViL0f)
|
||||
|
||||
Storytelling is an innate part of human nature. It's an idle pastime, it's an art form, it's a communication tool, it's a form of therapy and bonding. We all love to tell stories—you're reading one now—and the most powerful technologies we have are generally the things that enable us to express our creative ideas. The open source project [Twine][1] is a tool for doing just that.
|
||||
|
||||
Twine is an interactive story generator. It uses HTML, CSS, and Javascript to create self-contained adventure games, in the spirit of classics like [Zork][2] and [Colossal Cave][3]. Since Twine is largely an amalgamation of several open technologies, it is flexible enough to do a lot of multimedia tricks, rendering games a lot more like [HyperCard][4] than you might normally expect from HTML.
|
||||
|
||||
### Installing Twine
|
||||
|
||||
You can use Twine online or download it locally from its website. Unzip the download and click the `Twine` application icon to start it.
|
||||
|
||||
The default starting interface is pretty intuitive. Read its introductory material, then click the big green `+Story` button on the right to create a new story.
|
||||
|
||||
### Hello world
|
||||
|
||||
The basics are simple. A new storyboard contains one node, or "passage" in Twine's terminology, called `Untitled passage`. Roll over this passage to see the node's options, then click the pencil icon to edit its contents.
|
||||
|
||||
Name the passage something to indicate its position in your story. In the previous version of Twine, the starting passage had to be named **Start** , but in Twine 2, any title will work. It's still a good idea to make it sensible, so stick with something like `Start` or `Home` or `init`.
|
||||
|
||||
For the text contents of this story, type:
|
||||
```
|
||||
Hello [[world]]
|
||||
|
||||
```
|
||||
|
||||
If you're familiar with [wikitext][5], you can probably already guess that the word "world" in this passage is actually a link to another passage.
|
||||
|
||||
Your edits are saved automatically, so you can just close the editing dialogue box when finished. Back in your storyboard, Twine has detected that you've created a link and has provided a new passage for you, called `world`.
|
||||
|
||||
![developing story in Twine][7]
|
||||
|
||||
Developing a story in Twine
|
||||
|
||||
Open the new passage for editing and enter the text:
|
||||
```
|
||||
This was made with Twine.
|
||||
|
||||
```
|
||||
|
||||
To test your very short story, click the play button in the lower-right corner of the Twine window.
|
||||
|
||||
It's not much, but it's a start!
|
||||
|
||||
You can add more navigational choices by adding another link in double brackets, which generates a new passage, until you tell whatever tale you want to tell. It really is as simple as that.
|
||||
|
||||
To publish your adventure, click the story title in the lower-left corner of the storyboard window and select **Publish to file**. This saves your whole project as one HTML file. Upload that one file to your website, or send it to friends and have them open it in a web browser, and you've just made and delivered your very first text adventure.
|
||||
|
||||
### Advanced Twineage
|
||||
|
||||
Knowing only enough to build this `hello world` story, you can make a great text-based adventure consisting of exploration and choices. As quick starts go, that's not too bad. Like all good open source technology, there's no ceiling on this, and you can take it much much farther with a few additional tricks.
|
||||
|
||||
Twine projects work as well as they do partly because of a JavaScript backend called Harlowe. It adds all the pretty transitions and some UI styling, handles basic multimedia functions, and provides some special macros to reduce the amount of code you would have to write for some advanced tasks. This is open source, though, so naturally there are alternatives.
|
||||
|
||||
[SugarCube][8] is an alternate JavaScript library for Twine that handles media, media playback functions, advanced linking for passages, UI elements, save files, and much more. It can turn your basic text adventure into a multimedia extravaganza rivaling such adventure games as Myst or Beneath the Steel Sky.
|
||||
|
||||
### Installing SugarCube
|
||||
|
||||
To install the SugarCube backend for your project:
|
||||
|
||||
* [Download the SugarCube library][9]. Even though Twine ships with an earlier version of SugarCube, you should download the latest version.
|
||||
|
||||
* Once you've downloaded it, unzip the archive and place it in a sensible location. If you're not used to keeping files organized or [managing creative assets][10] for project development, put the unzipped SugarCube directory into your Twine directory for safekeeping.
|
||||
|
||||
* The SugarCube directory contains only a few files, with the actual code in `format.js`. If you're on Linux, right-click on the file and select **Copy**.
|
||||
|
||||
* In Twine, return to your project library by clicking the house icon in the lower-left corner of the Twine window.
|
||||
|
||||
* Click the **Formats** button in the right sidebar of Twine. In the **Add a New Format** tab, paste in the file path to `format.js` and click the green **Add** button.
|
||||
|
||||
![Install Sugarcube add format][12]
|
||||
|
||||
Installing Sugarcube: Click the Add button to add a new format in Twine
|
||||
|
||||
If you're not on Linux, type the file path manually in this format:
|
||||
|
||||
`file:///home/your-username/path/to/SugarCube-2/format.js`
|
||||
|
||||
|
||||
|
||||
|
||||
### Using SugarCube
|
||||
|
||||
To switch a project to SugarCube, enter the storyboard mode of your project.
|
||||
|
||||
In the story board view, click the title of your storyboard in the lower-left corner of the Twine window and select **Change Story Format**.
|
||||
|
||||
In the **Story format** window that appears, select the SugarCube 2.x option.
|
||||
|
||||
![Story format sugarcube][14]
|
||||
|
||||
Select SugarCube in the Story Format window
|
||||
|
||||
### Images
|
||||
|
||||
Before adding images, audio, or video to a Twine project, create a project directory in which to keep copies of your assets. This is vital, because these assets remain separate from the HTML file that Twine exports, so the final step of creating your story will be to take your exported HTML file and drop it in place alongside all the media it needs. If you're used to programming, video editing, or web design, this is a familiar discipline, but if you're new to this kind of content creation, you may not have encountered this before, so be especially diligent in organizing your assets.
|
||||
|
||||
Create a project directory somewhere. Inside this directory, create a subdirectory called **img** for your images, `audio` for your audio, `video` for video, and so on.
|
||||
|
||||
![Create a directory in Twine][16]
|
||||
|
||||
Create subdirectories for your project files in Twine
|
||||
|
||||
For this example, I use an image from [openclipart.org][17]. You can use this, or something similar. Regardless of what you use, place your image in your **img** directory.
|
||||
|
||||
Continuing with the hello_world project, you can add an image to one of the passages using SugarCube's image syntax:
|
||||
```
|
||||
<img src="img/earth.svg" alt="An image of the world." />
|
||||
|
||||
Hello [[world]].
|
||||
|
||||
```
|
||||
|
||||
If you try to play your project after adding your images, you'll find that all the image links are broken. This is because Twine is located outside of your project directory. To test a multimedia Twine project, export it as a file and place the file in your project directory. Don't put it inside any of the subdirectories you created; simply place it in your project directory and open it in a web browser.
|
||||
|
||||
![View media in sugarcube][19]
|
||||
|
||||
Previewing media files added to Twine project
|
||||
|
||||
Other media files function in basically the same way, utilizing HTML5 media tags to display the media and SugarCube macros to control when playback begins and ends.
|
||||
|
||||
### Variables and programming
|
||||
|
||||
You can do a lot by leading a player to one passage or another depending on what choices they have made, but you can cut down on how many passages you need by using variables.
|
||||
|
||||
If you have never programmed before, take a moment to read through my [introduction to programming concepts][20]. The article uses Python, but all the same concepts apply to Twine and basically any other programming language you're likely to encounter.
|
||||
|
||||
For example, since the hello_world story is initially set on Earth, the next step in the story could be to offer a variety of trips to other worlds. Each time the reader returns to Earth, the game can display a tally of the worlds they have visited. This would be essentially impossible to do linearly, because you would never be able to tell which path a reader has taken in their exploration. For instance, one reader might visit Mars first, then Mercury. Another might never go to Mars at all, instead visiting Jupiter, Saturn, and then Mercury. You would have to make one passage for every possible combination, and that solution simply doesn't scale.
|
||||
|
||||
With variables, however, you can track a reader's progress and display messages accordingly.
|
||||
|
||||
To make this work, you must set a variable each time a reader reaches a new planet. In the game universe of the hello_world game, planets are actually open source projects, so each time a user visits a passage about an open source project, set a variable to "prove" that the reader has visited.
|
||||
|
||||
Variables in SugarCube syntax are set with the <<set>> macro. SugarCube has lots of macros, and they're all handy. This example project uses a few.
|
||||
|
||||
Change the second passage you created to provide the reader a few new options for exploration:
|
||||
```
|
||||
This was made in [[Twine]] on [[Linux]].
|
||||
|
||||
<<choice Start "Return to Earth.">>
|
||||
|
||||
```
|
||||
|
||||
You're using the <<choice>> macro here, which links any string of text straight back to a given passage. In this case, the <<choice>> macro links the string "Return to Earth" to the Start passage.
|
||||
|
||||
In the new passage, insert this text:
|
||||
```
|
||||
Twine is an interactive story framework. It runs on all operating systems, but I prefer to use it on [[Linux]].
|
||||
|
||||
|
||||
|
||||
<<set $twine to true>>
|
||||
|
||||
<<choice Start "Return to Earth.">>
|
||||
|
||||
```
|
||||
|
||||
In this code, you use the <<set>> macro to create a new variable called `$twine`. This variable is a Boolean, because you're just setting it to "true". You'll see why that's significant soon.
|
||||
|
||||
In the `Linux` passage, enter this text:
|
||||
```
|
||||
Linux is an open source [[Unix]]-like operating system.
|
||||
|
||||
|
||||
|
||||
<<set $linux to true>>
|
||||
|
||||
<<choice Start "Return to Earth.">>
|
||||
|
||||
```
|
||||
|
||||
And in the `Unix` passage:
|
||||
```
|
||||
BSD is an open source version of AT&T's Unix operating system.
|
||||
|
||||
|
||||
|
||||
<<set $bsd to true>>
|
||||
|
||||
<<choice Start "Return to Earth.">>
|
||||
|
||||
```
|
||||
|
||||
Now that the story has five passages for a reader to explore, it's time to use SugarCube to detect which variable has been set each time a reader returns to Earth.
|
||||
|
||||
To detect the state of a variable and generate HTML accordingly, use the <<if>> macro.
|
||||
```
|
||||
<img src="img/earth.png" alt="An image of the world." />
|
||||
|
||||
|
||||
|
||||
Hello [[world]].
|
||||
|
||||
<ul>
|
||||
|
||||
<<if $twine is trueliPlanet Twine/li/if>>
|
||||
|
||||
<<if $linux is trueliPlanet Linux/li/if>>
|
||||
|
||||
<<if $bsd is trueliPlanet BSD/li/if>>
|
||||
|
||||
</ul>
|
||||
|
||||
```
|
||||
|
||||
For testing purposes, you can press the Play button in the lower-right corner. You won't see your image, but look past that in the interest of testing.
|
||||
|
||||
![complex story board][22]
|
||||
|
||||
A more complex story board
|
||||
|
||||
Navigate through the story, returning to Earth periodically. Notice that a tally of each place you visited appears at the bottom of the Start passage each time you return.
|
||||
|
||||
There's nothing explaining why the list of places visited is appearing, though. Can you figure out how to explain the tally of explored passages to the reader?
|
||||
|
||||
You could just preface the tally list with an introductory sentence like "So far you have visited:" but when the user first arrives, the list will be empty so your introductory sentence will be introducing nothing.
|
||||
|
||||
A better way to manage it is with one more variable to indicate that the user has left Earth.
|
||||
|
||||
Change the `world` passage:
|
||||
```
|
||||
This was made in [[Twine]] on [[Linux]].
|
||||
|
||||
|
||||
|
||||
<<set $offworld to true>>
|
||||
|
||||
<<choice Start "Return to Earth.">>
|
||||
|
||||
```
|
||||
|
||||
Then use another <<if>> macro to detect whether or not the `$offworld` variable is set to `true`.
|
||||
|
||||
The way Twine parses wikitext sometimes results in more blank lines than you intend, so to compress the list of places visited, use the <<nobr>> macro to prevent line breaks.
|
||||
```
|
||||
<img src="img/earth.png" alt="An image of the world." />
|
||||
|
||||
|
||||
|
||||
Hello [[world]].
|
||||
|
||||
<<nobr>>
|
||||
|
||||
<<ul>>
|
||||
|
||||
<<if $twine is trueliPlanet Twine/li/if>>
|
||||
|
||||
<<if $linux is trueliPlanet Linux/li/if>>
|
||||
|
||||
<<if $bsd is trueliPlanet BSD/li/if>>
|
||||
|
||||
<</ul>>
|
||||
|
||||
<</nobr>>
|
||||
|
||||
```
|
||||
|
||||
Try playing the story again. Notice that the reader isn't welcomed back to Earth until they have left Earth.
|
||||
|
||||
### Explore everything
|
||||
|
||||
SugarCube is a powerful engine. Using it is often a question of knowing what's available rather than not having the ability to do something. Luckily, its documentation is very good, so refer to its [macro][23] list often.
|
||||
|
||||
You can make further modifications to your project by changing the CSS stylesheet. To do this, click the title of your project in story board mode and select **Edit Story Stylesheet**. If you're familiar with JavaScript, you can also script your stories with the **Edit Story JavaScript**.
|
||||
|
||||
There's no limit to what Twine can do as your interactive fiction engine. It can create text adventures, and it can serve as a prototype for more complex games, point-and-click RPGs, business presentations, [late night talk show supplements][24], and just about anything else you can imagine. Explore the [Twine wiki][25], take a look at other people's works on the [Interactive Fiction Database][26], and then make your own.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/18/2/twine-gaming
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
译者:[译者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
|
||||
[1]:https://twinery.org/
|
||||
[2]:http://i7-dungeon.sourceforge.net/index.html
|
||||
[3]:https://opensource.com/article/17/6/revisit-colossal-cave-adventure-open-adventure
|
||||
[4]:https://en.wikipedia.org/wiki/HyperCard
|
||||
[5]:https://www.mediawiki.org/wiki/Wikitext
|
||||
[7]:https://opensource.com/sites/default/files/images/life-uploads/start.jpg (starting a story in Twine)
|
||||
[8]:http://www.motoslave.net/sugarcube/
|
||||
[9]:https://www.motoslave.net/sugarcube/2
|
||||
[10]:https://opensource.com/article/17/7/managing-creative-assets-planter
|
||||
[12]:https://opensource.com/sites/default/files/images/life-uploads/add.png (install sugarcube add format)
|
||||
[14]:https://opensource.com/sites/default/files/images/life-uploads/format.png (story format sugarcube)
|
||||
[16]:https://opensource.com/sites/default/files/images/life-uploads/dir.png (Creating directories in Twine)
|
||||
[17]:https://openclipart.org/detail/10912/earth-globe-oceania
|
||||
[19]:https://opensource.com/sites/default/files/images/life-uploads/sugarcube.png (view media sugarcube twine)
|
||||
[20]:https://opensource.com/article/17/10/python-101
|
||||
[22]:https://opensource.com/sites/default/files/images/life-uploads/complexer_0.png (complex story board)
|
||||
[23]:https://www.motoslave.net/sugarcube/2/docs/macros.html
|
||||
[24]:http://www.cbs.com/shows/the-late-show-with-stephen-colbert/escape-from-the-man-sized-cabinet/
|
||||
[25]:https://twinery.org/wiki/twine2:guide
|
||||
[26]:http://ifdb.tads.org/
|
@ -0,0 +1,80 @@
|
||||
Linux rmdir Command for Beginners (with Examples)
|
||||
======
|
||||
|
||||
So we've already discussed [the rm command][1] that's primarily used for deleting files and directories from the Linux command line. However, there's another, related command line utility that is specifically aimed at removing directories. The tool in question is **rmdir** , and in this tutorial, we will discuss the basics of it using some easy to understand examples.
|
||||
|
||||
#### Linux rmdir command
|
||||
|
||||
As the name suggests, the rmdir command is focused at removing directories, although empty-ones only. Following is its syntax:
|
||||
|
||||
```
|
||||
rmdir [OPTION]... DIRECTORY...
|
||||
```
|
||||
|
||||
And here's how the man page explains it:
|
||||
```
|
||||
Remove the DIRECTORY(ies), if they are empty.
|
||||
|
||||
```
|
||||
|
||||
The following Q&A-styled examples should give you a good idea on how this utility works.
|
||||
|
||||
#### Q1. How rmdir works?
|
||||
|
||||
That's pretty straight forward - just pass the directory name as input to the command. For example:
|
||||
|
||||
```
|
||||
rmdir test-dir
|
||||
```
|
||||
|
||||
[![How rmdir works][2]][3]
|
||||
|
||||
#### Q2. How to make rmdir ignore non-empty directories.
|
||||
|
||||
BY default, the rmdir command throws an error if you try deleting a non-empty directory. However, if you want, you can suppress this behavior of rmdir using the --ignore-fail-on-non-empty option.
|
||||
|
||||
For example:
|
||||
|
||||
[![How to make rmdir ignore non-empty directories][4]][5]
|
||||
|
||||
#### Q3. How to make rmdir remove parent directories as well?
|
||||
|
||||
Just like in the case of [mkdir][6], you can also ask rmdir to perform its operation on parent directories. What that means is, you can also delete parent directories of a directory in one go. This feature is accessible through the -p command line option.
|
||||
|
||||
For example, the following command will delete both 'test' and 'test-dir' directories.
|
||||
|
||||
```
|
||||
rmdir -p test/test-dir/
|
||||
```
|
||||
|
||||
**Note** : For this operation to work, all parent directories should not contain anything other than the empty-directory being deleted.
|
||||
|
||||
#### Q4. What is the difference between rmdir and rm -r ?
|
||||
|
||||
If you remember, you can also delete directories using the rm command by enabling the -r option it provides. So what's the difference between that and rmdir? Well, the answer is rmdir only works in the case of empty directories - there's no way whatsoever you can use to make rmdir delete non-empty directories.
|
||||
|
||||
So rmdir is a useful in tool in those situations where you otherwise need to check if a directory is empty before deleting it.
|
||||
|
||||
#### Conclusion
|
||||
|
||||
As you'll agree, rmdir isn't a complex command to understand and use. Plus, it offers only a handful command line options. We've discussed almost all of them here, so practice the examples mentioned in this article, and you should be good to go. Just in case you need, [here's the man page][7] for rmdir.
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.howtoforge.com/linux-rmdir-command/
|
||||
|
||||
作者:[Himanshu Arora][a]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://www.howtoforge.com
|
||||
[1]:https://www.howtoforge.com/linux-rm-command/
|
||||
[2]:https://www.howtoforge.com/images/command-tutorial/rm-basic-usage1.png
|
||||
[3]:https://www.howtoforge.com/images/command-tutorial/big/rm-basic-usage1.png
|
||||
[4]:https://www.howtoforge.com/images/command-tutorial/rmdir-ignore-nonempty.png
|
||||
[5]:https://www.howtoforge.com/images/command-tutorial/big/rmdir-ignore-nonempty.png
|
||||
[6]:https://www.howtoforge.com/linux-mkdir-command/
|
||||
[7]:https://linux.die.net/man/1/rmdir
|
192
sources/tech/20180210 How to create AWS ec2 key using Ansible.md
Normal file
192
sources/tech/20180210 How to create AWS ec2 key using Ansible.md
Normal file
@ -0,0 +1,192 @@
|
||||
How to create AWS ec2 key using Ansible
|
||||
======
|
||||
|
||||
I wanted to create Amazon EC2 Key pair using Ansible tool. I do not want to use AWS CLI. Is it possible to create AWS ec2 key using Ansible?
|
||||
|
||||
You need to use ec2_key module of Ansible. This module has a dependency on python-boto version 2.5 or above. boto is nothing but a python interface to Amazon Web Services using API. You can use boto for services like Amazon S3, Amazon EC2 and others. In short, you need ansible installed along with boto module. Let us see how to install boto and use it with Ansbile.
|
||||
|
||||
### Step 1 – [Install latest version of Ansible on Ubuntu Linux][1]
|
||||
|
||||
You must [configure the PPA on your system to install the latest version of ansible][2]. To manage the repositories that you install software from various PPA (Personal Package Archives). It allow you to upload Ubuntu source packages to be built and published as an apt repository by Launchpad. Type the following [apt-get command][3] or [apt command][4]:
|
||||
```
|
||||
$ sudo apt update
|
||||
$ sudo apt upgrade
|
||||
$ sudo apt install software-properties-common
|
||||
```
|
||||
Next add ppa:ansible/ansible to your system’s Software Source:
|
||||
```
|
||||
$ sudo apt-add-repository ppa:ansible/ansible
|
||||
```
|
||||
Update your repos and install ansible:
|
||||
```
|
||||
$ sudo apt update
|
||||
$ sudo apt install ansible
|
||||
```
|
||||
Install boto:
|
||||
```
|
||||
$ pip3 install boto3
|
||||
```
|
||||
|
||||
#### A note about installing Ansible on CentOS/RHEL 7.x
|
||||
|
||||
You [need to setup EPEL repo on a CentOS and RHEL 7.x][5] along with the [yum command][6]:
|
||||
```
|
||||
$ cd /tmp
|
||||
$ wget https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
|
||||
$ ls *.rpm
|
||||
$ sudo yum install epel-release-latest-7.noarch.rpm
|
||||
$ sudo yum install ansible
|
||||
```
|
||||
Install boto:
|
||||
```
|
||||
$ pip install boto3
|
||||
```
|
||||
|
||||
### Step 2 – Configure boto
|
||||
|
||||
You need to setup AWS credentials/API keys. See “[AWS Security Credentials][7]” documents on how to create a programmatic API key. Create a directory called ~/.aws using the mkdir command and setup API keys:
|
||||
```
|
||||
$ mkdir -pv ~/.aws/
|
||||
$ vi ~/.aws/credentials
|
||||
```
|
||||
```
|
||||
[default]
|
||||
aws_access_key_id = YOUR-ACCESS-KEY-HERE
|
||||
aws_secret_access_key = YOUR-SECRET-ACCESS-KEY-HERE
|
||||
```
|
||||
|
||||
Also setup default [AWS region][8]:
|
||||
`$ vi ~/.aws/config`
|
||||
Sample outputs:
|
||||
```
|
||||
[default]
|
||||
region = us-west-1
|
||||
```
|
||||
|
||||
Test your boto setup with API by creating a simple python program named test-boto.py:
|
||||
```
|
||||
#!/usr/bin/python3
|
||||
# A simple program to test boto and print s3 bucket names
|
||||
import boto3
|
||||
t = boto3.resource('s3')
|
||||
for b in t.buckets.all():
|
||||
print(b.name)
|
||||
```
|
||||
|
||||
Run it as follows:
|
||||
`$ python3 test-boto.py`
|
||||
Sample outputs:
|
||||
```
|
||||
nixcraft-images
|
||||
nixcraft-backups-cbz
|
||||
nixcraft-backups-forum
|
||||
|
||||
```
|
||||
|
||||
The output confirmed that Python-boto working correctly using AWS API.
|
||||
|
||||
### Step 3 – Create AWS ec2 key using Ansible
|
||||
|
||||
Create a playbook named ec2.key.yml as follows:
|
||||
```
|
||||
---
|
||||
- hosts: local
|
||||
connection: local
|
||||
gather_facts: no
|
||||
tasks:
|
||||
|
||||
- name: Create a new EC2 key
|
||||
ec2_key:
|
||||
name: nixcraft-key
|
||||
region: us-west-1
|
||||
register: ec2_key_result
|
||||
|
||||
- name: Save private key
|
||||
copy: content="{{ ec2_key_result.key.private_key }}" dest="./aws.nixcraft.pem" mode=0600
|
||||
when: ec2_key_result.changed
|
||||
```
|
||||
|
||||
Where,
|
||||
|
||||
* ec2_key: – Maintains ec2 key pair.
|
||||
* name: nixcraft_key – Name of the key pair.
|
||||
* region: us-west-1 – The AWS region to use.
|
||||
* register: ec2_key_result : Save result of generated key to ec2_key_result variable.
|
||||
* copy: content="{{ ec2_key_result.key.private_key }}" dest="./aws.nixcraft.pem" mode=0600 : Sets the contents of ec2_key_result.key.private_key to a file named aws.nixcraft.pem in the current directory. Set mode of the file to 0600 (unix file permissions).
|
||||
* when: ec2_key_result.changed : Only save when ec2_key_result changed is set to true. We don’t want to overwrite our key file.
|
||||
|
||||
|
||||
|
||||
You must create hosts file as follows too:
|
||||
```
|
||||
[local]
|
||||
localhost
|
||||
|
||||
```
|
||||
|
||||
Run your playbook as follows:
|
||||
`$ ansible-playbook -i hosts ec2.key.yml`
|
||||
![](https://www.cyberciti.biz/media/new/faq/2018/02/How-to-create-AWS-ec2-key-using-Ansible.jpg)
|
||||
At the end you should have a private key named aws.nixcraft.pem that you can use with AWS EC2. To view your key use the [cat command][9]:
|
||||
```
|
||||
$ cat aws.nixcraft.pem
|
||||
```
|
||||
If you have EC2 VM, use it as follows:
|
||||
```
|
||||
$ ssh -i aws.nixcraft.pem user@ec2-vm-dns-name
|
||||
```
|
||||
|
||||
#### Finding out info about python data structure variable names such as ec2_key_result.changed and ec2_key_result.key.private_key
|
||||
|
||||
You must be wondering how come I am using variable names such as ec2_key_result.changed and ec2_key_result.key.private_key. Are they defined somewhere? Values are returned from API calls. Simply run the ansible-playbook command with the -v option to see such info:
|
||||
`$ ansible-playbook -v -i hosts ec2.key.yml`
|
||||
![](https://www.cyberciti.biz/media/new/faq/2018/02/ansible-verbose-output.jpg)
|
||||
|
||||
### How do I delete a key?
|
||||
|
||||
Use the following ec2-key-delete.yml:
|
||||
```
|
||||
---
|
||||
- hosts: local
|
||||
connection: local
|
||||
gather_facts: no
|
||||
tasks:
|
||||
|
||||
- name: Delete a EC2 key
|
||||
ec2_key:
|
||||
name: nixcraft-key
|
||||
region: us-west-1
|
||||
# absent means delete keypair
|
||||
state: absent
|
||||
```
|
||||
|
||||
Run it as follows:
|
||||
`$ ansible-playbook -i hosts ec2-key-delete.yml`
|
||||
|
||||
|
||||
### about the author
|
||||
|
||||
The author is the creator of nixCraft and a seasoned sysadmin, DevOps engineer, and a trainer for the Linux operating system/Unix shell scripting. Get the **latest tutorials on SysAdmin, Linux/Unix and open source topics via[RSS/XML feed][10]** or [weekly email newsletter][11].
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.cyberciti.biz/faq/how-to-create-aws-ec2-key-using-ansible/
|
||||
|
||||
作者:[Vivek Gite][a]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://www.cyberciti.biz
|
||||
[1]:https://www.cyberciti.biz/faq/how-to-install-and-configure-latest-version-of-ansible-on-ubuntu-linux/
|
||||
[2]:https://www.cyberciti.biz/faq/ubuntu-sudo-add-apt-repository-command-not-found-error/
|
||||
[3]:https://www.cyberciti.biz/tips/linux-debian-package-management-cheat-sheet.html (See Linux/Unix apt-get command examples for more info)
|
||||
[4]:https://www.cyberciti.biz/faq/ubuntu-lts-debian-linux-apt-command-examples/ (See Linux/Unix apt command examples for more info)
|
||||
[5]:https://www.cyberciti.biz/faq/installing-rhel-epel-repo-on-centos-redhat-7-x/
|
||||
[6]:https://www.cyberciti.biz/faq/rhel-centos-fedora-linux-yum-command-howto/ (See Linux/Unix yum command examples for more info)
|
||||
[7]:https://docs.aws.amazon.com/general/latest/gr/aws-security-credentials.html
|
||||
[8]:https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Concepts.RegionsAndAvailabilityZones.html
|
||||
[9]:https://www.cyberciti.biz/faq/linux-unix-appleosx-bsd-cat-command-examples/ (See Linux/Unix cat command examples for more info)
|
||||
[10]:https://www.cyberciti.biz/atom/atom.xml
|
||||
[11]:https://www.cyberciti.biz/subscribe-to-weekly-linux-unix-newsletter-for-sysadmin/
|
@ -0,0 +1,297 @@
|
||||
学习你的工具:驾驭你的 Git 历史
|
||||
============================================================
|
||||
|
||||
在你的日常工作中,不可能每天都从头开始去开发一个新的应用程序。而真实的情况是,在日常工作中,我们大多数时候所面对的都是遗留下来的一个代码库,我们能够去修改一些特性的内容或者现存的一些代码行,是我们在日常工作中很重要的一部分。而这也就是分布式版本控制系统 `git` 的价值所在。现在,我们来深入了解怎么去使用 `git` 的历史以及如何很轻松地去浏览它的历史。
|
||||
|
||||
### Git 历史
|
||||
|
||||
首先和最重要的事是,什么是 `git` 历史?正如其名字一样,它是一个 `git` 仓库的提交历史。它包含一堆提交信息,其中有它们的作者的名字、提交的哈希值以及提交日期。查看一个 `git` 仓库历史的方法很简单,就是一个 `git log` 命令。
|
||||
|
||||
> _*旁注:**为便于本文的演示,我们使用 Ruby 在 Rails 仓库的 `master` 分支。之所以选择它的理由是因为,Rails 有很好的 `git` 历史,有很好的提交信息、引用以及每个变更的解释。如果考虑到代码库的大小、维护者的年龄和数据,Rails 肯定是我见过的最好的仓库。当然了,我并不是说其它 `git` 仓库做的不好,它只是我见过的比较好的一个仓库。_
|
||||
|
||||
因此,回到 Rails 仓库。如果你在 Ralis 仓库上运行 `git log`。你将看到如下所示的输出:
|
||||
|
||||
```
|
||||
commit 66ebbc4952f6cfb37d719f63036441ef98149418
|
||||
Author: Arthur Neves <foo@bar.com>
|
||||
Date: Fri Jun 3 17:17:38 2016 -0400
|
||||
|
||||
Dont re-define class SQLite3Adapter on test
|
||||
|
||||
We were declaring in a few tests, which depending of the order load will cause an error, as the super class could change.
|
||||
|
||||
see https://github.com/rails/rails/commit/ac1c4e141b20c1067af2c2703db6e1b463b985da#commitcomment-17731383
|
||||
|
||||
commit 755f6bf3d3d568bc0af2c636be2f6df16c651eb1
|
||||
Merge: 4e85538 f7b850e
|
||||
Author: Eileen M. Uchitelle <foo@bar.com>
|
||||
Date: Fri Jun 3 10:21:49 2016 -0400
|
||||
|
||||
Merge pull request #25263 from abhishekjain16/doc_accessor_thread
|
||||
|
||||
[skip ci] Fix grammar
|
||||
|
||||
commit f7b850ec9f6036802339e965c8ce74494f731b4a
|
||||
Author: Abhishek Jain <foo@bar.com>
|
||||
Date: Fri Jun 3 16:49:21 2016 +0530
|
||||
|
||||
[skip ci] Fix grammar
|
||||
|
||||
commit 4e85538dddf47877cacc65cea6c050e349af0405
|
||||
Merge: 082a515 cf2158c
|
||||
Author: Vijay Dev <foo@bar.com>
|
||||
Date: Fri Jun 3 14:00:47 2016 +0000
|
||||
|
||||
Merge branch 'master' of github.com:rails/docrails
|
||||
|
||||
Conflicts:
|
||||
guides/source/action_cable_overview.md
|
||||
|
||||
commit 082a5158251c6578714132e5c4f71bd39f462d71
|
||||
Merge: 4bd11d4 3bd30d9
|
||||
Author: Yves Senn <foo@bar.com>
|
||||
Date: Fri Jun 3 11:30:19 2016 +0200
|
||||
|
||||
Merge pull request #25243 from sukesan1984/add_i18n_validation_test
|
||||
|
||||
Add i18n_validation_test
|
||||
|
||||
commit 4bd11d46de892676830bca51d3040f29200abbfa
|
||||
Merge: 99d8d45 e98caf8
|
||||
Author: Arthur Nogueira Neves <foo@bar.com>
|
||||
Date: Thu Jun 2 22:55:52 2016 -0400
|
||||
|
||||
Merge pull request #25258 from alexcameron89/master
|
||||
|
||||
[skip ci] Make header bullets consistent in engines.md
|
||||
|
||||
commit e98caf81fef54746126d31076c6d346c48ae8e1b
|
||||
Author: Alex Kitchens <foo@bar.com>
|
||||
Date: Thu Jun 2 21:26:53 2016 -0500
|
||||
|
||||
[skip ci] Make header bullets consistent in engines.md
|
||||
```
|
||||
|
||||
正如你所见,`git log` 展示了提交哈希、作者和他的 email 以及提交日期。当然,`git` 输出的可定制性很强大,它允许你去定制 `git log` 命令的输出格式。比如说,我们希望看到提交的信息显示在一行上,我们可以运行 `git log --oneline`,它将输出一个更紧凑的日志:
|
||||
|
||||
```
|
||||
66ebbc4 Dont re-define class SQLite3Adapter on test
|
||||
755f6bf Merge pull request #25263 from abhishekjain16/doc_accessor_thread
|
||||
f7b850e [skip ci] Fix grammar4e85538 Merge branch 'master' of github.com:rails/docrails
|
||||
082a515 Merge pull request #25243 from sukesan1984/add_i18n_validation_test
|
||||
4bd11d4 Merge pull request #25258 from alexcameron89/master
|
||||
e98caf8 [skip ci] Make header bullets consistent in engines.md
|
||||
99d8d45 Merge pull request #25254 from kamipo/fix_debug_helper_test
|
||||
818397c Merge pull request #25240 from matthewd/reloadable-channels
|
||||
2c5a8ba Don't blank pad day of the month when formatting dates
|
||||
14ff8e7 Fix debug helper test
|
||||
```
|
||||
|
||||
如果你想看 `git log` 的全部选项,我建议你去查阅 `git log` 的 man 页面,你可以在一个终端中输入 `man git-log` 或者 `git help log` 来获得。
|
||||
|
||||
> _**小提示:**如果你觉得 `git log` 看起来太恐怖或者过于复杂,或者你觉得看它太无聊了,我建议你去寻找一些 `git` GUI 命令行工具。在以前的文章中,我使用过 [GitX][1] ,我觉得它很不错,但是,由于我看命令行更“亲切”一些,在我尝试了 [tig][2] 之后,就再也没有去用过它。_
|
||||
|
||||
### 查找尼莫
|
||||
|
||||
现在,我们已经知道了关于 `git log` 命令一些很基础的知识之后,我们来看一下,在我们的日常工作中如何使用它更加高效地浏览历史。
|
||||
|
||||
假如,我们怀疑在 `String#classify` 方法中有一个预期之外的行为,我们希望能够找出原因,并且定位出实现它的代码行。
|
||||
|
||||
为达到上述目的,你可以使用的第一个命令是 `git grep`,通过它可以找到这个方法定义在什么地方。简单来说,这个命令输出了给定的某些“样品”的匹配行。现在,我们来找出定义它的方法,它非常简单 —— 我们对 `def classify` 运行 grep,然后看到的输出如下:
|
||||
|
||||
```
|
||||
➜ git grep 'def classify'
|
||||
|
||||
activesupport/lib/active_support/core_ext/string/inflections.rb: def classifyactivesupport/lib/active_support/inflector/methods.rb: def classify(table_name)tools/profile: def classify
|
||||
```
|
||||
|
||||
现在,虽然我们已经看到这个方法是在哪里创建的,但是,并不能够确定它是哪一行。如果,我们在 `git grep` 命令上增加 `-n` 标志,`git` 将提供匹配的行号:
|
||||
|
||||
```
|
||||
➜ git grep -n 'def classify'
|
||||
|
||||
activesupport/lib/active_support/core_ext/string/inflections.rb:205: def classifyactivesupport/lib/active_support/inflector/methods.rb:186: def classify(table_name)tools/profile:112: def classify
|
||||
```
|
||||
|
||||
更好看了,是吧?考虑到上下文,我们可以很轻松地找到,这个方法在`activesupport/lib/active_support/core_ext/string/inflections.rb` 的第 205 行的 `classify` 方法,它看起来像这样,是不是很容易?
|
||||
|
||||
```
|
||||
# Creates a class name from a plural table name like Rails does for table names to models.
|
||||
# Note that this returns a string and not a class. (To convert to an actual class
|
||||
# follow +classify+ with +constantize+.)
|
||||
#
|
||||
# 'ham_and_eggs'.classify # => "HamAndEgg"
|
||||
# 'posts'.classify # => "Post"
|
||||
def classify
|
||||
ActiveSupport::Inflector.classify(self)
|
||||
end
|
||||
```
|
||||
|
||||
尽管这个方法我们找到的是在 `String` 上的一个常见的调用,它涉及到`ActiveSupport::Inflector` 上的另一个方法,使用了相同的名字。获得了 `git grep` 的结果,我们可以很轻松地导航到这里,因此,我们看到了结果的第二行, `activesupport/lib/active_support/inflector/methods.rb` 在 186 行上。我们正在寻找的方法是:
|
||||
|
||||
```
|
||||
# Creates a class name from a plural table name like Rails does for table
|
||||
# names to models. Note that this returns a string and not a Class (To
|
||||
# convert to an actual class follow +classify+ with constantize).
|
||||
#
|
||||
# classify('ham_and_eggs') # => "HamAndEgg"
|
||||
# classify('posts') # => "Post"
|
||||
#
|
||||
# Singular names are not handled correctly:
|
||||
#
|
||||
# classify('calculus') # => "Calculus"
|
||||
def classify(table_name)
|
||||
# strip out any leading schema name
|
||||
camelize(singularize(table_name.to_s.sub(/.*\./, ''.freeze)))
|
||||
end
|
||||
```
|
||||
|
||||
酷!考虑到 Rails 仓库的大小,我们借助 `git grep` 找到它,用时没有超越 30 秒。
|
||||
|
||||
### 那么,最后的变更是什么?
|
||||
|
||||
我们已经掌握了有用的方法,现在,我们需要搞清楚这个文件所经历的变更。由于我们已经知道了正确的文件名和行数,我们可以使用 `git blame`。这个命令展示了一个文件中每一行的最后修订者和修订的内容。我们来看一下这个文件最后的修订都做了什么:
|
||||
|
||||
```
|
||||
git blame activesupport/lib/active_support/inflector/methods.rb
|
||||
```
|
||||
|
||||
虽然我们得到了这个文件每一行的最后的变更,但是,我们更感兴趣的是对指定的方法(176 到 189 行)的最后变更。让我们在 `git blame` 命令上增加一个选项,它将只显示那些行。此外,我们将在命令上增加一个 `-s` (阻止) 选项,去跳过那一行变更时的作者名字和修订(提交)的时间戳:
|
||||
|
||||
```
|
||||
git blame -L 176,189 -s activesupport/lib/active_support/inflector/methods.rb
|
||||
|
||||
9fe8e19a 176) #Creates a class name from a plural table name like Rails does for table
|
||||
5ea3f284 177) # names to models. Note that this returns a string and not a Class (To
|
||||
9fe8e19a 178) # convert to an actual class follow +classify+ with #constantize).
|
||||
51cd6bb8 179) #
|
||||
6d077205 180) # classify('ham_and_eggs') # => "HamAndEgg"
|
||||
9fe8e19a 181) # classify('posts') # => "Post"
|
||||
51cd6bb8 182) #
|
||||
51cd6bb8 183) # Singular names are not handled correctly:
|
||||
5ea3f284 184) #
|
||||
66d6e7be 185) # classify('calculus') # => "Calculus"
|
||||
51cd6bb8 186) def classify(table_name)
|
||||
51cd6bb8 187) # strip out any leading schema name
|
||||
5bb1d4d2 188) camelize(singularize(table_name.to_s.sub(/.*\./, ''.freeze)))
|
||||
51cd6bb8 189) end
|
||||
```
|
||||
|
||||
现在,`git blame` 命令的输出展示了指定行的全部内容以及它们各自的修订。让我们来看一下指定的修订,换句话说就是,每个变更都修订了什么,我们可以使用 `git show` 命令。当指定一个修订哈希(像 `66d6e7be`)作为一个参数时,它将展示这个修订的全部内容。包括作者名字、时间戳以及完整的修订内容。我们来看一下 188 行最后的修订都做了什么?
|
||||
|
||||
```
|
||||
git show 5bb1d4d2
|
||||
```
|
||||
|
||||
你亲自做实验了吗?如果没有做,我直接告诉你结果,这个令人惊叹的 [提交][3] 是由 [Schneems][4] 做的,他通过使用 frozen 字符串做了一个非常有趣的性能优化,这在我们当前的上下文中是非常有意义的。但是,由于我们在这个假设的调试会话中,这样做并不能告诉我们当前问题所在。因此,我们怎么样才能够通过研究来发现,我们选定的方法经过了哪些变更?
|
||||
|
||||
### 搜索日志
|
||||
|
||||
现在,我们回到 `git` 日志,现在的问题是,怎么能够看到 `classify` 方法经历了哪些修订?
|
||||
|
||||
`git log` 命令非常强大,因此它提供了非常多的列表选项。我们尝试去看一下保存了这个文件的 `git` 日志内容。使用 `-p` 选项,它的意思是在 `git` 日志中显示这个文件的完整补丁:
|
||||
|
||||
```
|
||||
git log -p activesupport/lib/active_support/inflector/methods.rb
|
||||
```
|
||||
|
||||
这将给我们展示一个很长的修订列表,显示了对这个文件的每个修订。但是,正如下面所显示的,我们感兴趣的是对指定行的修订。对命令做一个小的修改,只显示我们希望的内容:
|
||||
|
||||
```
|
||||
git log -L 176,189:activesupport/lib/active_support/inflector/methods.rb
|
||||
```
|
||||
|
||||
`git log` 命令接受了 `-L` 选项,它有一个行的范围和文件名做为参数。它的格式可能有点奇怪,格式解释如下:
|
||||
|
||||
```
|
||||
git log -L <start-line>,<end-line>:<path-to-file>
|
||||
```
|
||||
|
||||
当我们去运行这个命令之后,我们可以看到对这些行的一个修订列表,它将带我们找到创建这个方法的第一个修订:
|
||||
|
||||
```
|
||||
commit 51xd6bb829c418c5fbf75de1dfbb177233b1b154
|
||||
Author: Foo Bar <foo@bar.com>
|
||||
Date: Tue Jun 7 19:05:09 2011 -0700
|
||||
|
||||
Refactor
|
||||
|
||||
diff--git a/activesupport/lib/active_support/inflector/methods.rb b/activesupport/lib/active_support/inflector/methods.rb
|
||||
--- a/activesupport/lib/active_support/inflector/methods.rb
|
||||
+++ b/activesupport/lib/active_support/inflector/methods.rb
|
||||
@@ -58,0 +135,14 @@
|
||||
+ # Create a class name from a plural table name like Rails does for table names to models.
|
||||
+ # Note that this returns a string and not a Class. (To convert to an actual class
|
||||
+ # follow +classify+ with +constantize+.)
|
||||
+ #
|
||||
+ # Examples:
|
||||
+ # "egg_and_hams".classify # => "EggAndHam"
|
||||
+ # "posts".classify # => "Post"
|
||||
+ #
|
||||
+ # Singular names are not handled correctly:
|
||||
+ # "business".classify # => "Busines"
|
||||
+ def classify(table_name)
|
||||
+ # strip out any leading schema name
|
||||
+ camelize(singularize(table_name.to_s.sub(/.*\./, '')))
|
||||
+ end
|
||||
```
|
||||
|
||||
现在,我们再来看一下 —— 它是在 2011 年提交的。`git` 可以让我们重回到这个时间。这是一个很好的例子,它充分说明了足够的提交信息对于重新了解当时的上下文环境是多么的重要,因为从这个提交信息中,我们并不能获得足够的信息来重新理解当时的创建这个方法的上下文环境,但是,话说回来,你**不应该**对此感到恼怒,因为,你看到的这些项目,它们的作者都是无偿提供他们的工作时间和精力来做开源工作的。(向开源项目贡献者致敬!)
|
||||
|
||||
回到我们的正题,我们并不能确认 `classify` 方法最初实现是怎么回事,考虑到这个第一次的提交只是一个重构。现在,如果你认为,“或许、有可能、这个方法不在 176 行到 189 行的范围之内,那么就你应该在这个文件中扩大搜索范围”,这样想是对的。我们看到在它的修订提交的信息中提到了“重构”这个词,它意味着这个方法可能在那个文件中是真实存在的,只是在重构之后它才存在于那个行的范围内。
|
||||
|
||||
但是,我们如何去确认这一点呢?不管你信不信,`git` 可以再次帮助你。`git log` 命令有一个 `-S` 选项,它可以传递一个特定的字符串作为参数,然后去查找代码变更(添加或者删除)。也就是说,如果我们执行 `git log -S classify` 这样的命令,我们可以看到所有包含 `classify` 字符串的变更行的提交。
|
||||
|
||||
如果你在 Ralis 仓库上运行上述命令,首先你会发现这个命令运行有点慢。但是,你应该会发现 `git` 真的解析了在那个仓库中的所有修订来匹配这个字符串,因为仓库非常大,实际上它的运行速度是非常快的。在你的指尖下 `git` 再次展示了它的强大之处。因此,如果去找关于 `classify` 方法的第一个修订,我们可以运行如下的命令:
|
||||
|
||||
```
|
||||
git log -S 'def classify'
|
||||
```
|
||||
|
||||
它将返回所有这个方法的引用和修改的地方。如果你一直往下看,你将看到日志中它的最后的提交:
|
||||
|
||||
```
|
||||
commit db045dbbf60b53dbe013ef25554fd013baf88134
|
||||
Author: David Heinemeier Hansson <foo@bar.com>
|
||||
Date: Wed Nov 24 01:04:44 2004 +0000
|
||||
Initial
|
||||
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@4 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
|
||||
```
|
||||
|
||||
很酷!是吧?它初次被提交到 Rails,是由 DHHD 在一个 `svn` 仓库上做的!这意味着 `classify` 提交到 Rails 仓库的大概时间。现在,我们去看一下这个提交的所有变更信息,我们运行如下的命令:
|
||||
|
||||
```
|
||||
git show db045dbbf60b53dbe013ef25554fd013baf88134
|
||||
```
|
||||
|
||||
非常好!我们终于找到它的根源了。现在,我们使用 `git log -S 'def classify'` 的输出,结合 `git log -L` 命令来跟踪这个方法都发生了哪些变更。
|
||||
|
||||
### 下次见
|
||||
|
||||
当然,我们并不会真的去修改任何 bug,因为我们只是去尝试使用一些 `git` 命令,来演示如何查看 `classify` 方法的演变历史。但是不管怎样,`git` 是一个非常强大的工具,我们必须学好它、用好它。我希望这篇文章可以帮助你掌握更多的关于如何使用 `git` 的知识。
|
||||
|
||||
你喜欢这些内容吗?
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
作者简介:
|
||||
|
||||
后端工程师,对 Ruby、Go、微服务、构建弹性架构来解决大规模部署带来的挑战很感兴趣。我在阿姆斯特丹的 Rails Girls 担任顾问,维护着一个小而精的列表,并且经常为开源做贡献。
|
||||
|
||||
那个列表是我写的关于软件开发、编程语言以及任何我感兴趣的东西。
|
||||
|
||||
------
|
||||
|
||||
via: https://ieftimov.com/learn-your-tools-navigating-git-history
|
||||
|
||||
作者:[Ilija Eftimov ][a]
|
||||
译者:[qhwdw](https://github.com/qhwdw)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://ieftimov.com/
|
||||
[1]:http://gitx.frim.nl/
|
||||
[2]:https://github.com/jonas/tig
|
||||
[3]:https://github.com/rails/rails/commit/5bb1d4d288d019e276335465d0389fd2f5246bfd
|
||||
[4]:https://twitter.com/schneems
|
@ -0,0 +1,180 @@
|
||||
Ansible:像系统管理员一样思考的自动化框架
|
||||
======
|
||||
|
||||
这些年来,我已经写了许多关于DevOps工具的文章,也培训了这方面的人员,尽管这些工具很棒,但很明显,大多数都是按照开发人员的思路设计出来的。这也没有什么问题,因为以编程的方式接近配置管理是重点。不过,直到我开始接触Ansible,我才觉得这才是系统管理员喜欢的东西。
|
||||
|
||||
喜欢的一部分原因是Ansible与客户端计算机通信的方式,是通过SSH的。作为系统管理员,你们都非常熟悉通过SSH连接到计算机,所以从单词“去”的角度来看,你对Ansible的了解要比其他选择更好。
|
||||
|
||||
考虑到这一点,我打算写一些文章,探讨如何使用Ansible。这是一个很好的系统,但是当我第一次接触到这个系统的时候,不知道如何开始。也不是学习曲线陡峭。事实上,问题是在开始使用Ansible之前,我并没有太多的东西要学,这才是让人感到困惑的。例如,如果您不必安装客户端程序(Ansible没有在客户端计算机上安装任何软件),那么您将如何启动?
|
||||
|
||||
### 踏出第一步
|
||||
|
||||
起初Ansible对我来说非常困难的原因在于配置服务器/客户端的关系是非常灵活的,我不知道我该从何入手。事实是,Ansible并不关心你如何设置SSH系统。它会利用你现有的任何配置。需要考虑以下几件事情:
|
||||
|
||||
1. Ansible需要通过SSH连接到客户端计算机。
|
||||
2. 连接后,Ansible需要提升权限才能配置系统,安装软件包等等。
|
||||
|
||||
不幸的是,这两个考虑真的带来了一堆蠕虫。连接到远程计算机并提升权限是一件可怕的事情。出于某种原因,当您只需在远程计算机上安装代理并使用Chef或Puppet处理特权升级问题时,感觉就不那么差了。 Ansible并非不安全,而是安全的决定权在你手中。
|
||||
|
||||
接下来,我将列出一系列潜在的配置,以及每个配置的优缺点。这不是一个详尽的清单,但是你会受到正确的启发,去思考在你自己的环境中什么是理想的配置。也需要注意,我不会提到像Vagrant这样的系统,因为尽管Vagrant在构建测试和开发的敏捷架构时非常棒,但是和一堆服务器是非常不同的,因此考虑因素是极不相似的。
|
||||
|
||||
### 一些SSH场景
|
||||
|
||||
1)在Ansible配置中,以root用户密码进入远程计算机。
|
||||
|
||||
拥有这个想法是一个非常可怕的开始。这个设置的“优点”是它消除了对特权提升的需要,并且远程服务器上不需要其他用户帐户。 但是,这种便利的成本是不值得的。 首先,大多数系统不会让你在不改变默认配置的情况下以root身份进行SSH登录。 由于默认的配置都在固定的位置,坦率地说,允许root用户远程连接是一个不好的主意。 其次,将root密码放在Ansible机器上的纯文本配置文件中是不合适的。 真的,我提到了这种可能性,因为这是可能的,但这是应该避免的。 请记住,Ansible允许你自己配置连接,它可以让你做真正愚蠢的事情。 但是请不要这么做。
|
||||
|
||||
2)使用存储在Ansible配置中的密码,以普通用户的身份进入远程计算机。
|
||||
|
||||
这种情况的一个优点是它不需要太多的客户端配置。 大多数用户默认情况下都可以使用SSH,因此Ansible应该能够使用凭据并且能够正常登录。 我个人不喜欢在配置文件中以纯文本形式存储密码,但至少不是root密码。 如果您使用此方法,请务必考虑远程服务器上的权限提升方式。 我知道我还没有谈到权限提升,但是如果你在配置文件中配置了一个密码,这个密码可能会被用来获得sudo访问权限。 因此,一旦发生泄露,您不仅已经泄露了远程用户的帐户,还可能泄露整个系统。
|
||||
|
||||
3)以普通用户身份进入远程计算机,使用具有空密码的密钥对进行身份验证。
|
||||
|
||||
这消除了将密码存储在配置文件中的弊端,至少在登录的过程中消除了。 没有密码的密钥对并不理想,但这是我经常做的事情。 在我的个人内部网络中,我通常使用没有密码的密钥对来自动执行许多事情,如需要身份验证的定时任务。 这不是最安全的选择,因为私钥泄露意味着可以无限制地访问远程用户的帐户,但是相对于在配置文件中存储密码我更喜欢这种方式。
|
||||
|
||||
4)以普通用户的身份通过SSH连接到远程计算机,使用通过密码保护的密钥对进行身份验证。
|
||||
|
||||
这是处理远程访问的一种非常安全的方式,因为它需要两种不同的身份验证因素来解密:私钥和密码。 如果你只是以交互方式运行Ansible,这可能是理想的设置。 当你运行命令时,Ansible会提示你输入私钥,然后使用密钥对登录到远程系统。 是的,只需使用标准密码登录并且不用在配置文件中指定密码即可完成,但是如果不管怎样都要在命令行上输入密码,那为什么不在保护层添加密钥对呢?
|
||||
|
||||
5)使用密码保护密钥对进行SSH连接,但是使用ssh-agent“解锁”私钥。
|
||||
|
||||
这并不能完美地解决无人值守,自动化的Ansible命令的问题,但是它确实也使安全设置变得相当方便。 ssh-agent程序一次验证密码,然后使用该验证进行后续连接。当我使用Ansible时,这是我想要做的事情。如果我是完全值得信任的,我通常仍然使用没有密码的密钥对,但是这通常是因为我在我的家庭服务器上工作,是不是容易受到攻击的。
|
||||
|
||||
在配置SSH环境时还要记住一些其他注意事项。 也许你可以限制Ansible用户(通常是你的本地用户名),以便它只能从一个特定的IP地址登录。 也许您的Ansible服务器可以位于不同的子网中,位于强大的防火墙之后,因此其私钥更难以远程访问。 也许Ansible服务器本身没有安装SSH服务器,所以根本没法访问。 同样,Ansible的优势之一是它使用SSH协议进行通信,而且这是一个协议,你有多年的时间把你的系统调整到最适合你的环境的效果。 我不是宣传“最佳实践”的忠实粉丝,因为实际上最好的做法是考虑你的环境,并选择最适合你情况的设置。
|
||||
|
||||
### 权限提升
|
||||
|
||||
一旦您的Ansible服务器通过SSH连接到它的客户端,就需要能够提升特权。 如果你选择了上面的选项1,那么你已经是root了,这是一个有争议的问题。 但是由于没有人选择选项1(对吧?),您需要考虑客户端计算机上的普通用户如何获得访问权限。 Ansible支持各种权限提升的系统,但在Linux中,最常用的选项是sudo和su。 和SSH一样,有几种情况需要考虑,虽然肯定还有其他选择。
|
||||
|
||||
1)使用su提升权限。
|
||||
|
||||
对于RedHat/CentOS用户来说,可能默认是使用su来获得系统访问权限。 默认情况下,这些系统在安装过程中配置了root密码,要想获得特殊访问权限,您需要输入该密码。使用su的问题在于,虽说它可以让您完全访问远程系统,不过您确实可以完全访问远程系统。 (是的,这是讽刺。)另外,su程序没有使用密钥对进行身份验证的能力,所以密码必须以交互方式输入或存储在配置文件中。 由于它实际上是root密码,因此将其存储在配置文件中听起来像一个可怕的想法,因为它就是。
|
||||
|
||||
2)使用sudo提升权限。
|
||||
|
||||
这就是Debian/Ubuntu系统的配置方式。 正常用户组中的用户可以使用sudo命令并使用root权限执行该命令。 随之而来的是,这仍然存在密码存储或交互式输入的问题。 由于在配置文件中存储用户的密码看起来不太可怕,我猜这是使用su的一个步骤,但是如果密码被泄露,仍然可以完全访问系统。 (毕竟,输入`sudo`和`su -`都将允许用户成为root用户,就像拥有root密码一样。)
|
||||
|
||||
3) 使用sudo提升权限,并在sudoers文件中配置NOPASSWD。
|
||||
|
||||
再者,在我的本地环境中,我就是这么做的。 这并不完美,因为它给予用户帐户无限制的root权限,并且不需要任何密码。 但是,当我这样做并且使用没有密码短语的SSH密钥对时,我可以让Ansible命令更轻松的自动化。 我会再次注意到,虽然这很方便,但这不是一个非常安全的想法。
|
||||
|
||||
4)使用sudo提升权限,并在特定的可执行文件上配置NOPASSWD。
|
||||
|
||||
这个想法可能是安全性和便利性的最佳折衷。 基本上,如果你知道你打算用Ansible做什么,那么你可以为远程用户使用的那些应用程序提供NOPASSWD权限。 这可能会让人有些困惑,因为Ansible使用Python来处理很多事情,但是有足够的尝试和错误,你应该能够弄清原理。 这是额外的工作,但确实消除了一些明显的安全漏洞。
|
||||
|
||||
### 计划实施
|
||||
|
||||
一旦你决定如何处理Ansible认证和权限提升,就需要设置它。 在熟悉Ansible之后,您可能会使用该工具来帮助“引导”新客户端,但首先手动配置客户端非常重要,以便您知道发生了什么事情。 将你熟悉的事情变得自动化比从自动化开始要好。
|
||||
|
||||
我已经写过关于SSH密钥对的文章,网上有无数的设置类的文章。 来自Ansible服务器的简短版本看起来像这样:
|
||||
|
||||
```
|
||||
# ssh-keygen
|
||||
# ssh-copy-id -i .ssh/id_dsa.pub remoteuser@remote.computer.ip
|
||||
# ssh remoteuser@remote.computer.ip
|
||||
```
|
||||
|
||||
如果您在创建密钥对时选择不使用密码,最后一步您应该可以直接进入远程计算机,而不用输入密码或密钥串。
|
||||
|
||||
为了在sudo中设置权限提升,您需要编辑sudoers文件。 你不应该直接编辑文件,而是使用:
|
||||
|
||||
```
|
||||
# sudo visudo
|
||||
```
|
||||
|
||||
这将打开sudoers文件并允许您安全地进行更改(保存时会进行错误检查,所以您不会意外地因为输入错误将自己锁住)。 这个文件中有一些例子,所以你应该能够弄清楚如何分配你想要的确切的权限。
|
||||
|
||||
一旦配置完成,您应该在使用Ansible之前进行手动测试。 尝试SSH到远程客户端,然后尝试使用您选择的任何方法提升权限。 一旦你确认配置的这种方式可以连接,就可以安装Ansible了。
|
||||
|
||||
### Ansible安装
|
||||
|
||||
由于Ansible程序仅安装在一台计算机上,因此开始并不是一件繁重的工作。 Red Hat/Ubuntu系统的软件包安装有点不同,但都不是很困难。
|
||||
|
||||
在Red Hat/CentOS中,首先启用EPEL库:
|
||||
|
||||
```
|
||||
sudo yum install epel-release
|
||||
```
|
||||
|
||||
然后安装Ansible:
|
||||
|
||||
```
|
||||
sudo yum install ansible
|
||||
```
|
||||
|
||||
在Ubuntu中,首先启用Ansible PPA:
|
||||
|
||||
```
|
||||
sudo apt-add-repository spa:ansible/ansible
|
||||
(press ENTER to access the key and add the repo)
|
||||
```
|
||||
|
||||
然后安装Ansible:
|
||||
|
||||
```
|
||||
sudo apt-get update
|
||||
sudo apt-get install ansible
|
||||
```
|
||||
|
||||
### Ansible主机文件配置
|
||||
|
||||
Ansible系统无法知道您希望它控制哪个客户端,除非您给它一个计算机列表。 该列表非常简单,看起来像这样:
|
||||
|
||||
```
|
||||
# file /etc/ansible/hosts
|
||||
|
||||
[webservers]
|
||||
blogserver ansible_host=192.168.1.5
|
||||
wikiserver ansible_host=192.168.1.10
|
||||
|
||||
[dbservers]
|
||||
mysql_1 ansible_host=192.168.1.22
|
||||
pgsql_1 ansible_host=192.168.1.23
|
||||
```
|
||||
|
||||
括号内的部分是指定组。 单个主机可以列在多个组中,而Ansible可以指向单个主机或组。 这也是配置文件,比如纯文本密码的东西将被存储,如果这是你计划的那种设置。 配置文件中的每一行配置一个主机地址,并且可以在ansible_host语句之后添加多个声明。 一些有用的选项是:
|
||||
|
||||
```
|
||||
ansible_ssh_pass
|
||||
ansible_become
|
||||
ansible_become_method
|
||||
ansible_become_user
|
||||
ansible_become_pass
|
||||
```
|
||||
|
||||
### Ansible Vault保险库
|
||||
|
||||
(译者注:Vault作为 ansible 的一项新功能可将例如passwords,keys等敏感数据文件进行加密,而非明文存放)
|
||||
|
||||
我也应该注意到,尽管安装程序比较复杂,而且不是在您首次进入Ansible世界时可能会做的事情,但该程序确实提供了一种方法来加密保险库中的密码。 一旦您熟悉Ansible,并且希望将其投入生产,将这些密码存储在加密的Ansible库中是非常理想的。 但是本着先学会爬再学会走的精神,我建议首先在非生产环境下使用无密码方法。
|
||||
|
||||
### 系统测试
|
||||
|
||||
最后,你应该测试你的系统,以确保客户端可以正常连接。 ping测试将确保Ansible计算机可以ping每个主机:
|
||||
|
||||
```
|
||||
ansible -m ping all
|
||||
```
|
||||
|
||||
运行后,如果ping成功,您应该看到每个定义的主机显示ping的消息:pong。 这实际上并没有测试认证,只是测试网络连接。 试试这个来测试你的认证:
|
||||
|
||||
```
|
||||
ansible -m shell -a 'uptime' webservers
|
||||
```
|
||||
|
||||
您应该可以看到webservers组中每个主机的运行时间命令的结果。
|
||||
|
||||
在后续文章中,我计划开始深入Ansible管理远程计算机的功能。 我将介绍各种模块,以及如何使用ad-hoc模式来完成一些按键操作,这些操作在命令行上单独处理都需要很长时间。 如果您没有从上面的示例Ansible命令中获得预期的结果,请花些时间确保身份验证正在运行。 如果遇到困难,请查阅[Ansible文档][1]获取更多帮助。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: http://www.linuxjournal.com/content/ansible-automation-framework-thinks-sysadmin
|
||||
|
||||
作者:[Shawn Powers][a]
|
||||
译者:[Flowsnow](https://github.com/Flowsnow)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:http://www.linuxjournal.com/users/shawn-powers
|
||||
[1]:http://docs.ansible.com
|
@ -0,0 +1,412 @@
|
||||
如何搭建“我的世界”服务器
|
||||
======
|
||||
我们将通过一个一步步的、新手友好的教程来向你展示如何搭建一个“我的世界”服务器。这将会是一个长期的多人游戏服务器,你可以与来自世界各地的朋友们一起玩,而不用在同一个局域网下。
|
||||
|
||||
### 如何搭建一个“我的世界”服务器 - 快速指南
|
||||
|
||||
如果你很急,想直达重点的话,这是我们的目录。我们推荐通读整篇文章。
|
||||
|
||||
* [学点东西][1] (可选)
|
||||
|
||||
* [再学点东西][2] (可选)
|
||||
|
||||
* [需求][3] (必读)
|
||||
|
||||
* [安装并运行“我的世界”服务器][4] (必读)
|
||||
|
||||
* [在你登出 VPS 后继续运行服务端][5] (可选)
|
||||
|
||||
* [让服务端随系统启动][6] (可选)
|
||||
|
||||
* [配置你的“我的世界”服务器][7] (必读)
|
||||
|
||||
* [常见问题][8] (可选)
|
||||
|
||||
在你开始行动之前,要先了解一些事情:
|
||||
|
||||
#### 为什么你不应该使用专门的“我的世界”服务器提供商
|
||||
|
||||
既然你正在阅读这篇文章,你肯定对搭建自己的“我的世界”服务器感兴趣。不应该使用专门的“我的世界”服务器提供商的原因有很多,以下是其中一些:
|
||||
|
||||
* 它们通常很慢。这是因为你是在和很多用户一起共享资源。这有的时候会超负荷,他们中很多都会超售。
|
||||
|
||||
* 你并不能完全控制”我的世界“服务端,或是真正的服务器。你没法按照你的意愿进行自定义。
|
||||
|
||||
* 你是受限制的。这种主机套餐或多或少都会有限制。
|
||||
|
||||
当然,使用现成的提供商也是有优点的。最好的就是你不用做下面这些操作。但是那还有什么意思呢?![🙂](https://s.w.org/images/core/emoji/2.3/svg/1f642.svg)
|
||||
|
||||
#### 为什么不应该用你的个人电脑作为”我的世界“服务器
|
||||
|
||||
我们注意到很多教程都展示的是如何在你自己的电脑上搭建服务器。这样做有一些弊端,比如:
|
||||
|
||||
* 你的家庭网络不够安全,无法抵挡 DDoS 攻击。游戏服务器通常容易被 DDoS 攻击,而你的家庭网络设置通常不够安全,来抵挡它们。很可能连小型攻击都无法阻挡。
|
||||
|
||||
* 你得处理端口转发。如果你试着在家庭网络中搭建”我的世界“服务器的话,你肯定会偶然发现端口转发的问题,并且处理时可能会有问题。
|
||||
|
||||
* 你得保持你的电脑一直开着。你的电费将会突破天际,并且你会增加不必要的硬件负载。大部分服务器硬件都是企业级的,提升了稳定性和持久性,专门设计用来处理负载。
|
||||
|
||||
* 你的家庭网络速度不够快。家庭网络并不是设计用来负载多人联机游戏的。即使你想搭建一个小型服务器,你也需要一个更好的网络套餐。幸运的是,数据中心有多个高速的、企业级的互联网连接,来保证他们达到(或尽量达到)100%在线。
|
||||
|
||||
* 你的硬件很可能不够好。再说一次,服务器使用的都是企业级硬件,最新最快的处理器、固态硬盘,等等。你的个人电脑很可能不是的。
|
||||
|
||||
* 你的个人电脑很可能是 Windows/MacOS。尽管这是有争议的,我们相信 Linux 更适合搭建游戏服务器。不用担心,搭建”我的世界“服务器不需要完全了解 Linux(尽管推荐这样)。我们会向你展示你需要了解的。
|
||||
|
||||
我们的建议是不要使用个人电脑,即使从技术角度来说你能做到。买一个云服务器并不是很贵。下面我们会向你展示如何在云服务器上搭建”我的世界“服务端。小心地遵守以下步骤,就很简单。
|
||||
|
||||
### 搭建一个”我的世界“服务器 - 需求
|
||||
|
||||
这是一些需求,你在教程开始之前需要拥有并了解它们:
|
||||
|
||||
* 你需要一个 [Linux 云服务器][9]。我们推荐 [Vultr][10]。这家价格便宜,服务质量高,客户支持很好,并且所有的服务器硬件都很高端。检查[“我的世界”服务器需求][11]来选择你需要哪种类型的服务器(像内存和硬盘之类的资源)。我们推荐每月 20 美元的套餐。他们也支持按小时收费,所以如果你只是临时需要服务器和朋友们联机的话,你的花费会更少。注册时选择 Ubuntu 16.04 发行版。在注册时选择离你的朋友们最近的地域。这样的话你就需要保护并管理服务器。如果你不想这样的话,你可以选择[托管的服务器][],这样的话服务器提供商可能会给你搭建好一个“我的世界”服务器。
|
||||
* 你需要一个 SSH 客户端来连接到你的 Linux 云服务器。新手通常建议使用 [PuTTy][13],但我们也推荐使用 [MobaXTerm][14]。也有很多 SSH 客户端,所以挑一个你喜欢的吧。
|
||||
* 你需要设置你的服务器(至少做好基本的安全设置)。谷歌一下你会发现很多教程。你也可以按照 [Linode 的 安全指南][15],然后在你的 [Vultr][16] 服务器上一步步操作。
|
||||
* 下面我们将会处理软件依赖,比如 Java。
|
||||
|
||||
终于,到我们真正的教程了:
|
||||
|
||||
### 如何在 Ubuntu(Linux)上搭建一个“我的世界”服务器
|
||||
|
||||
这篇教程是为 [Vultr][17] 上的 Ubuntu 16.04 撰写并测试可行的。但是这对 Ubuntu 14.04, [Ubuntu 18.04][18],以及其他基于 Ubuntu 的发行版,其他服务器提供商也是可行的。
|
||||
|
||||
我们使用默认的 Vanilla 服务端。你也可以使用像 CraftBukkit 或 Spigot 这样的服务端,来支持更多的自定义和插件。虽然如果你使用过多插件的话会毁了服务端。这各有优缺点。不管怎么说,下面的教程使用默认的 Vanilla 服务端,来使事情变得简单和更新手友好。如果有兴趣的话我们可能会发表一篇 CraftBukkit 的教程。
|
||||
|
||||
#### 1. 登陆到你的服务器
|
||||
|
||||
我们将使用 root 账户。如果你使用受限的账户的话,大部分命令都需要 ‘sudo’。做你没有权限的事情时会出现警告。
|
||||
|
||||
你可以通过 SSH 客户端来登陆你的服务器。使用你的 IP 和端口(大部分都是 22)。
|
||||
|
||||
在你登陆之后,确保你的[服务器安全][19]。
|
||||
|
||||
#### 2. 更新 Ubuntu
|
||||
|
||||
在你做任何事之前都要先更新你的 Ubuntu。你可以通过以下命令更新:
|
||||
|
||||
```
|
||||
apt-get update && apt-get upgrade
|
||||
```
|
||||
|
||||
在提示时敲击“回车键” 和/或 “y”。
|
||||
|
||||
#### 3. 安装必要的工具
|
||||
|
||||
在这篇教程中你需要一些工具和软件来编辑文本、长久保持服务端运行等。使用下面的命令安装:
|
||||
|
||||
```
|
||||
apt-get install nano wget screen bash default-jdk ufw
|
||||
```
|
||||
|
||||
其中一些可能已经安装好了。
|
||||
|
||||
#### 4. 下载“我的世界”服务端
|
||||
|
||||
首先,创建一个目录来保存你的“我的世界”服务端和其他文件:
|
||||
|
||||
```
|
||||
mkdir /opt/minecraft
|
||||
```
|
||||
|
||||
然后进入新目录:
|
||||
|
||||
```
|
||||
cd /opt/minecraft
|
||||
```
|
||||
|
||||
现在你可以下载“我的世界“服务端文件了。去往[下载页面][20]获取下载链接。使用wget下载文件:
|
||||
|
||||
```
|
||||
wget https://s3.amazonaws.com/Minecraft.Download/versions/1.12.2/minecraft_server.1.12.2.jar
|
||||
```
|
||||
|
||||
#### 5. 安装”我的世界“服务端
|
||||
|
||||
下载好了服务端 .jar 文件之后,你就需要先运行一下,它会生成一些文件,包括一个 eula.txt 许可文件。第一次运行的时候,它会返回一个错误并退出。这是正常的。使用下面的命令运行它:
|
||||
|
||||
```
|
||||
java -Xms2048M -Xmx3472M -jar minecraft_server.1.12.2.jar nogui
|
||||
```
|
||||
|
||||
”-Xms2048M“是你的服务端能使用的最小的内存,”-Xmx3472M“是最大的。[调整][21]基于你服务器的硬件资源。如果你在 [Vultr][22] 服务器上有 4GB 内存,并且不用服务器来干其他事情的话可以就这样留着不动。
|
||||
|
||||
在这条命令结束并返回一个错误之后,将会生成一个新的 eula.txt 文件。你需要同意那个文件里的协议。你可以通过下面这条命令将”eula=true“添加到文件中:
|
||||
|
||||
```
|
||||
sed -i.orig 's/eula=false/eula=true/g' eula.txt
|
||||
```
|
||||
|
||||
你现在可以通过和上面一样的命令来开启服务端并进入”我的世界“服务端控制台了:
|
||||
|
||||
```
|
||||
java -Xms2048M -Xmx3472M -jar minecraft_server.1.12.2.jar nogui
|
||||
```
|
||||
|
||||
确保你在 /opt/minecraft 目录,或者其他你安装你的 MC 服务端的目录下。
|
||||
|
||||
如果你只是测试或暂时需要的话,到这里就可以停了。如果你在登陆服务器时有问题的话,你就需要[配置你的防火墙][23]。
|
||||
|
||||
第一次成功启动服务端时会花费一点时间来生成。
|
||||
|
||||
我们将向你展示如何创建一个脚本来启动。
|
||||
|
||||
#### 6. 使用脚本启动“我的世界”服务端,让服务端长期运行并在启动时开启
|
||||
|
||||
方便起见,我们将创建一个自动启动服务端的 bash 脚本。
|
||||
|
||||
首先,使用 nano 创建一个 bash 脚本:
|
||||
|
||||
```
|
||||
nano /opt/minecraft/startminecraft.sh
|
||||
```
|
||||
|
||||
这将会打开一个新的(空白)文件。粘贴以下内容:
|
||||
|
||||
```
|
||||
#!/bin/bash
|
||||
cd /opt/minecraft/ && java -Xms2048M -Xmx3472M -jar minecraft_server.1.12.2.jar nogui
|
||||
```
|
||||
|
||||
如果你不熟悉 nano 的话 - 你可以使用“CTRL + X”,再敲击“Y”,然后回车。这个脚本将进入你先前创建的“我的世界”服务端并运行 Java 命令来开启服务端。你需要执行下面的命令来使脚本可执行:
|
||||
|
||||
```
|
||||
chmod +x startminecraft.sh
|
||||
```
|
||||
|
||||
然后,你就可以通过下面的命令随时运行服务端了:
|
||||
|
||||
```
|
||||
/opt/minecraft/startminecraft.sh
|
||||
```
|
||||
|
||||
但是,如果/当你登出 SSH 会话的话,服务端就会关闭。要想让服务端不登陆也持续运行的话,你可以使用 screen 会话。一个 screen 会话会一直运行,直到实际的服务器被关闭或重启。
|
||||
|
||||
使用下面的命令开启一个 screen 会话:
|
||||
|
||||
```
|
||||
screen -S minecraft
|
||||
```
|
||||
|
||||
一旦你进入了 screen 会话(看起来就像是你新建了一个 SSH 会话),你就可以使用先前创建的 bash 脚本来启动服务端:
|
||||
|
||||
```
|
||||
/opt/minecraft/startminecraft.sh
|
||||
```
|
||||
|
||||
要退出 screen 会话的话,你应该按 CTRL +A-D。即使你离开 screen 会话(断开的),服务端也会继续运行。你现在可以安全的登出 Ubuntu 服务器了,你创建的“我的世界”服务端将会继续运行。
|
||||
|
||||
但是,如果 Ubuntu 服务器重启或关闭了的话,screen 会话将不再起作用。所以**为了让我们之前做的这些在启动时自动运行**,做下面这些:
|
||||
|
||||
打开 /etc/rc.local 文件:
|
||||
|
||||
```
|
||||
nano /etc/rc.local
|
||||
```
|
||||
|
||||
在“exit 0”语句前添加如下内容:
|
||||
|
||||
```
|
||||
screen -dm -S minecraft /opt/minecraft/startminecraft.sh
|
||||
exit 0
|
||||
```
|
||||
|
||||
保存并关闭文件。
|
||||
|
||||
要访问“我的世界”服务端控制台,只需运行下面的命令来重新连接 screen 会话:
|
||||
|
||||
```
|
||||
screen -r minecraft
|
||||
```
|
||||
|
||||
现在就是这样。祝贺你,玩的开心!你现在可以连接到你的“我的世界”服务端或配置/修改它了。
|
||||
|
||||
### 配置你的 Ubuntu 服务器
|
||||
|
||||
你首先肯定要设置并确保你的 Ubuntu 服务器安全,如果你还没有这么做的话。按照[我们之前提及的指南][24]并谷歌一下来获取更多信息。你需要在服务器上配置的有这些:
|
||||
|
||||
#### 开启并配置防火墙
|
||||
|
||||
首先,如果防火墙还没有开启的话,你应该先开启先前安装的 UFW:
|
||||
|
||||
```
|
||||
ufw enable
|
||||
```
|
||||
|
||||
你应该开放默认的“我的世界”服务端端口:
|
||||
|
||||
```
|
||||
ufw allow 25565/tcp
|
||||
```
|
||||
|
||||
你应该根据你的使用情况开放或拒绝其他规则。如果你不用服务器负载网站的话,就应该拒绝 80 和 443 端口。谷歌一下 Ubuntu 的 UFW/防火墙指南,你会得到建议的。设置防火墙的时候小心一些,如果你屏蔽了 SSH 端口的话你会把自己锁在服务器外面。
|
||||
|
||||
由于这是默认端口,这个端口经常被扫描以及攻击。你可以通过屏蔽白名单之外的访问权限来阻挡攻击。
|
||||
|
||||
首先,你需要在你的 [server.properties][25] 文件中开启白名单模式。要开启的话,打开文件:
|
||||
|
||||
```
|
||||
nano /opt/minecraft/server.properties
|
||||
```
|
||||
|
||||
并将“white-list”行改为“true”:
|
||||
|
||||
```
|
||||
white-list=true
|
||||
```
|
||||
|
||||
保存并关闭文件。
|
||||
|
||||
然后重启你的服务器(重启你的服务器或重新运行启动脚本):
|
||||
|
||||
```
|
||||
/opt/minecraft/startminecraft.sh
|
||||
```
|
||||
|
||||
访问“我的世界”服务端控制台:
|
||||
|
||||
```
|
||||
screen -r minecraft
|
||||
```
|
||||
|
||||
如果你想要某人进入你的服务端,你需要通过以下命令把他们添加到白名单:
|
||||
|
||||
```
|
||||
whitelist add PlayerUsername
|
||||
```
|
||||
|
||||
运行以下命令来将他们移出白名单:
|
||||
|
||||
```
|
||||
whitelist remove PlayerUsername
|
||||
```
|
||||
|
||||
使用 CTRL + A-D 来退出 screen(服务器控制台)。值得注意的是,这会拒绝除白名单以外的所有人连接到服务端。
|
||||
|
||||
[![how to create a minecraft server](https://thishosting.rocks/wp-content/uploads/2018/01/create-a-minecraft-server.jpg)][26]
|
||||
|
||||
### 如何搭建“我的世界”服务器 - 常见问题
|
||||
|
||||
我们将解答一些有关“我的世界”服务器和我们的指南的常见问题。
|
||||
|
||||
#### 我该如何重启“我的世界”服务器?
|
||||
|
||||
如果你按照我们的教程来的话,包括开启了服务端随系统启动,你可以直接重启你的 Ubuntu 服务器。如果没有设置岁系统启动的话,你可以通过重新运行启动脚本来重启“我的世界”服务端:
|
||||
|
||||
```
|
||||
/opt/minecraft/startminecraft.sh
|
||||
```
|
||||
|
||||
#### 我该如何配置我的“我的世界”服务端?
|
||||
|
||||
你可以使用 [server.properties][27] 文件来配置你的服务端。查看“我的世界”维基来获取更多信息,你也可以什么都不动,它会工作的很好。
|
||||
|
||||
如果你想改变游戏模式、难度等诸如此类的东西,你可以使用服务端控制台。通过下面的命令访问服务端控制台:
|
||||
|
||||
```
|
||||
screen -r minecraft
|
||||
```
|
||||
|
||||
在这里执行[命令][28]。像下面这些命令:
|
||||
|
||||
```
|
||||
difficulty hard
|
||||
```
|
||||
|
||||
```
|
||||
gamemode survival @a
|
||||
```
|
||||
|
||||
你可能需要重新启动服务端,这取决于你使用了什么命令。你可以使用很多命令,查看[维基][29]来获取更多。
|
||||
|
||||
#### 我该如何升级我的“我的世界”服务端?
|
||||
|
||||
如果有新版本发布的话,你需要这样做:
|
||||
|
||||
进入”我的世界“目录:
|
||||
|
||||
```
|
||||
cd /opt/minecraft
|
||||
```
|
||||
|
||||
下载最新的版本,比如使用 wget 下载 1.12.3 版本:
|
||||
|
||||
```
|
||||
wget https://s3.amazonaws.com/Minecraft.Download/versions/1.12.3/minecraft_server.1.12.3.jar
|
||||
```
|
||||
|
||||
接下来,运行并构建新服务端:
|
||||
|
||||
```
|
||||
java -Xms2048M -Xmx3472M -jar minecraft_server.1.12.3.jar nogui
|
||||
```
|
||||
|
||||
最后,更新你的启动脚本:
|
||||
|
||||
```
|
||||
nano /opt/minecraft/startminecraft.sh
|
||||
```
|
||||
|
||||
更新版本号数字:
|
||||
|
||||
```
|
||||
#!/bin/bash
|
||||
cd /opt/minecraft/ && java -Xms2048M -Xmx3472M -jar minecraft_server.1.12.3.jar nogui
|
||||
```
|
||||
|
||||
现在你可以重启服务端了,一切都应该没有问题。
|
||||
|
||||
#### 为什么你们的教程这么长,而其他的只有 2 行那么长?!
|
||||
|
||||
我们想让这个教程对新手来说更友好,并且尽可能详细。我们还向你展示了了如何让服务端长期运行并跟随系统启动,我们向你展示了如何配置你的服务端以及所有的东西。我是说,你当然可以用几行来启动“我的世界”服务器,但那样的话绝对很烂,从不仅一方面说。
|
||||
|
||||
#### 我不知道 Linux 或者这里说的什么东西,我该如何搭建一个“我的世界”服务器呢?
|
||||
|
||||
只要通篇阅读我们的文章,复制粘贴几个命令就行了。如果你真的不知道该如何做的话,[我们可以帮你][30],或者直接找一个[托管的][31]服务器[提供商][32],让他们帮你做这些。
|
||||
|
||||
#### 我该如何在服务端上安装 mod 和插件?
|
||||
|
||||
我们的文章意图作一篇入门指南,你应该查看[“我的世界维基”][33],或者谷歌一下来获取更多信息。网上有很多教程。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://thishosting.rocks/how-to-make-a-minecraft-server/
|
||||
|
||||
作者:[ThisHosting.Rocks][a]
|
||||
译者:[heart4lor](https://github.com/heart4lor)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://thishosting.rocks
|
||||
[1]:https://thishosting.rocks/how-to-make-a-minecraft-server/#reasons
|
||||
[2]:https://thishosting.rocks/how-to-make-a-minecraft-server/#not-pc
|
||||
[3]:https://thishosting.rocks/how-to-make-a-minecraft-server/#requirements
|
||||
[4]:https://thishosting.rocks/how-to-make-a-minecraft-server/#make-minecraft-server
|
||||
[5]:https://thishosting.rocks/how-to-make-a-minecraft-server/#persistent
|
||||
[6]:https://thishosting.rocks/how-to-make-a-minecraft-server/#boot
|
||||
[7]:https://thishosting.rocks/how-to-make-a-minecraft-server/#configure-minecraft-server
|
||||
[8]:https://thishosting.rocks/how-to-make-a-minecraft-server/#faqs
|
||||
[9]:https://thishosting.rocks/cheap-cloud-hosting-providers-comparison/
|
||||
[10]:https://thishosting.rocks/go/vultr/
|
||||
[11]:https://minecraft.gamepedia.com/Server/Requirements/Dedicated
|
||||
[12]:https://thishosting.rocks/best-cheap-managed-vps/
|
||||
[13]:https://www.chiark.greenend.org.uk/~sgtatham/putty/
|
||||
[14]:https://mobaxterm.mobatek.net/
|
||||
[15]:https://www.linode.com/docs/security/securing-your-server/
|
||||
[16]:https://thishosting.rocks/go/vultr/
|
||||
[17]:https://thishosting.rocks/go/vultr/
|
||||
[18]:https://thishosting.rocks/ubuntu-18-04-new-features-release-date/
|
||||
[19]:https://www.linode.com/docs/security/securing-your-server/
|
||||
[20]:https://minecraft.net/en-us/download/server
|
||||
[21]:https://minecraft.gamepedia.com/Commands
|
||||
[22]:https://thishosting.rocks/go/vultr/
|
||||
[23]:https://thishosting.rocks/how-to-make-a-minecraft-server/#configure-minecraft-server
|
||||
[24]:https://www.linode.com/docs/security/securing-your-server/
|
||||
[25]:https://minecraft.gamepedia.com/Server.properties
|
||||
[26]:https://thishosting.rocks/wp-content/uploads/2018/01/create-a-minecraft-server.jpg
|
||||
[27]:https://minecraft.gamepedia.com/Server.properties
|
||||
[28]:https://minecraft.gamepedia.com/Commands
|
||||
[29]:https://minecraft.gamepedia.com/Commands
|
||||
[30]:https://thishosting.rocks/support/
|
||||
[31]:https://thishosting.rocks/best-cheap-managed-vps/
|
||||
[32]:https://thishosting.rocks/best-cheap-managed-vps/
|
||||
[33]:https://minecraft.gamepedia.com/Minecraft_Wiki
|
@ -0,0 +1,65 @@
|
||||
LKRG:Linux 的适用于运行时完整性检查的可加载内核模块
|
||||
======
|
||||
![LKRG logo][1]
|
||||
|
||||
开源社区的成员正在致力于一个 Linux 内核的新项目,它可以让内核更安全。命名为 Linux 内核运行时防护(Linux Kernel Runtime Guard,简称:LKRG),它是一个在 Linux 内核执行运行时完整性检查时的可加载内核模块。
|
||||
|
||||
它的用途是检测对 Linux 内核的已知的或未知的安全漏洞利用企图,以及去阻止这种攻击企图。
|
||||
|
||||
LKRG 也可以检测正在运行的进程的提权行为,在漏洞利用代码运行之前杀掉这个运行进程。
|
||||
|
||||
### 这个项目从 2011 年开始开发以来,首个版本已经发布。
|
||||
|
||||
因为这个项目开发的较早,LKRG 的当前版本仅仅是通过内核消息去报告违反内核完整性的行为,但是随着这个项目的成熟,一个完整的漏洞利用缓减系统将会部署。
|
||||
|
||||
LKRG 的成员 Alexander Peslyak 解释说,这个项目从 2011 年启动,并且 LKRG 已经经历了“预开发"阶段。
|
||||
|
||||
LKRG 的首个公开版本是 — LKRG v0.0 — 它现在可以从 [这个页面][2] 下载使用。[这里][3] 是这个项目的维基,为支持这个项目,它也有一个 [Patreon 页面][4]。
|
||||
|
||||
虽然 LKRG 还是一个开源项目,LKRG 的维护者也计划做一个 LKRG Pro 版本,这个版本将包含一个专用的 LKRG 发行版,它将支持对特定漏洞利用的检测,比如,容器泄漏。开发团队计划从 LKRG Pro 基金中提取部分资金用于保证项目的剩余工作。
|
||||
|
||||
### LKRG 是一个内核模块而不是一个补丁。
|
||||
|
||||
一个类似的项目是去增加一个内核监视功能(AKO),但是 LKRG 与 AKO 是不一样的,因为 LKRG 是一个内核加载模式而不是一个补丁。LKRG 开发团队决定将它设计为一个内核模块是因为,在内核上打补丁对安全性、系统稳定性以及性能都有很直接的影响。
|
||||
|
||||
而作为内核模块的方式,可以在每个系统上更容易部署去 LKRG,而不必去修改核心的内核代码,修改核心的内核代码非常复杂并且很容易出错。
|
||||
|
||||
LKRG 内核模块在目前主流的 Linux 发行版上都可以使用,比如,RHEL7、OpenVZ 7、Virtuozzo 7、以及 Ubuntu 16.04 到最新的主线版本。
|
||||
|
||||
### 它并非是一个完美的解决方案
|
||||
|
||||
LKRG 的创建者警告用户,他们并不认为 LKRG 是一个完美的解决方案,它**提供不了**坚不可摧和 100% 的安全。他们说,LKRG 是 "设计为**可旁通**的",并且仅仅提供了"多元化安全" 的**一个**方面。
|
||||
|
||||
```
|
||||
虽然 LKRG 可以防御许多对 Linux 内核的已存在的漏洞利用,而且也有可能会防御将来许多的(包括未知的)未特意设计去绕过 LKRG 的安全漏洞利用。它是设计为可旁通的(尽管有时候是以更复杂和/或低可利用为代价的)。因此,他们说 LKRG 通过多元化提供安全,就像运行一个不常见的操作系统内核一样,也就不会有真实运行一个不常见的操作系统的可用性弊端。
|
||||
```
|
||||
|
||||
LKRG 有点像基于 Windows 的防病毒软件,它也是工作于内核级别去检测漏洞利用和恶意软件。但是,LKRG 团队说,他们的产品比防病毒软件以及其它终端安全软件更加安全,因为它的基础代码量比较小,所以在内核级别引入新 bug 和漏洞的可能性就更小。
|
||||
|
||||
### 运行当前版本的 LKRG 大约会带来 6.5% 的性能损失
|
||||
|
||||
Peslyak 说 LKRG 是非常适用于 Linux 机器的,它在修补内核的安全漏洞后不需要重启动机器。LKRG 允许用户去持续运行带有安全措施的机器,直到在一个计划的维护窗口中测试和部署关键的安全补丁为止。
|
||||
|
||||
经测试显示,安装 LKRG v0.0 后大约会产生 6.5% 性能影响,但是,Peslyak 说将在后续的开发中持续降低这种影响。
|
||||
|
||||
测试也显示,LKRG 检测到了 CVE-2014-9322 (BadIRET)、CVE-2017-5123 (waitid(2) missing access_ok)、以及 CVE-2017-6074 (use-after-free in DCCP protocol) 的漏洞利用企图,但是没有检测到 CVE-2016-5195 (Dirty COW) 的漏洞利用企图。开发团队说,由于前面提到的”可旁通“的设计策略,LKRG 没有检测到 Dirty COW 提权攻击。
|
||||
|
||||
```
|
||||
在 Dirty COW 的测试案例中,由于 bug 机制的原因,使得 LKRG 发生了 "旁通",并且这也是一种利用方法,它也是将来类似的以用户空间为目标的绕过 LKRG 的一种方法。这样的漏洞利用是否会是普通情况(不太可能!除非 LKRG 或者类似机制的软件流行起来),以及对它的可用性的(负面的)影响是什么?(对于那些直接目标是用户空间的内核漏洞来说,这不太重要,也并不简单)。
|
||||
```
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.bleepingcomputer.com/news/linux/lkrg-linux-to-get-a-loadable-kernel-module-for-runtime-integrity-checking/
|
||||
|
||||
作者:[Catalin Cimpanu][a]
|
||||
译者:[qhwdw](https://github.com/qhwdw)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://www.bleepingcomputer.com/author/catalin-cimpanu/
|
||||
[1]:https://www.bleepstatic.com/content/posts/2018/02/04/LKRG-logo.png
|
||||
[2]:http://www.openwall.com/lkrg/
|
||||
[3]:http://openwall.info/wiki/p_lkrg/Main
|
||||
[4]:https://www.patreon.com/p_lkrg
|
339
translated/tech/20180206 Simple TensorFlow Examples.md
Normal file
339
translated/tech/20180206 Simple TensorFlow Examples.md
Normal file
@ -0,0 +1,339 @@
|
||||
TensorFlow 的简单例子
|
||||
======
|
||||
|
||||
![](https://process.filestackapi.com/cache=expiry:max/resize=width:700/compress/XWiMrodDQb2Qg6RxyDDG)
|
||||
|
||||
在本次推送中,我们将看一些例子,并从中感受到在定义张量和使用张量做数学计算方面有多么容易,我还会举些别的机器学习相关的例子。
|
||||
|
||||
## TensorFlow 是什么?
|
||||
|
||||
TensorFlow 是 Google 为了解决复杂计算耗时过久的问题而开发的一个库。
|
||||
|
||||
事实上,TensorFlow 能干许多事。比如:
|
||||
|
||||
* 解复杂数学表达式
|
||||
* 机器学习技术。你往其中输入一组数据样本用以训练,接着给出另一组数据样本用以预测基于训练的数据的结果。这就是人工智能了!
|
||||
* 支持 GPU 。你可以使用 GPU (图像处理单元)替代 CPU 以更快的运算。 TensorFlow 有两个版本: CPU 版本和 GPU 版本。
|
||||
|
||||
|
||||
开始写例子前,需要了解一些基本知识。
|
||||
|
||||
## 什么是张量?
|
||||
|
||||
张量是 TensorFlow 使用的主要的数据块,它很像 TensorFlow 用来处理数据的变量。张量拥有维度和类型的属性。
|
||||
|
||||
维度指张量的行和列数,读到后面你就知道了,可以定义一维张量、二维张量和三维张量。
|
||||
|
||||
类型指张量元素的数据类型。
|
||||
|
||||
## 定义一维张量
|
||||
|
||||
可以这样来定义一个张量:创建一个 NumPy (译者注:NumPy 系统是 Python 的一种开源数字扩展,包含一个强大的 N 维数组对象 Array,用来存储和处理大型矩阵 )或者一个 [Python list][1] ,然后使用 tf_convert_to_tensor 函数将其转化成张量。
|
||||
|
||||
可以像下面这样,使用 NumPy 创建一个数组:
|
||||
```
|
||||
import numpy as np arr = np.array([1, 5.5, 3, 15, 20])
|
||||
|
||||
arr = np.array([1, 5.5, 3, 15, 20])
|
||||
|
||||
```
|
||||
|
||||
运行结果显示了这个数组的维度和形状。
|
||||
```
|
||||
import numpy as np
|
||||
|
||||
arr = np.array([1, 5.5, 3, 15, 20])
|
||||
|
||||
print(arr)
|
||||
|
||||
print (arr.ndim)
|
||||
|
||||
print (arr.shape)
|
||||
|
||||
print (arr.dtype)
|
||||
|
||||
```
|
||||
|
||||
它和 Python list 很像,但是在这里,元素之间没有逗号。
|
||||
|
||||
现在使用 tf_convert_to_tensor 函数把这个数组转化为张量。
|
||||
```
|
||||
import numpy as np
|
||||
|
||||
import tensorflow as tf
|
||||
|
||||
arr = np.array([1, 5.5, 3, 15, 20])
|
||||
|
||||
tensor = tf.convert_to_tensor(arr,tf.float64)
|
||||
|
||||
print(tensor)
|
||||
|
||||
```
|
||||
|
||||
这次的运行结果显示了张量具体的含义,但是不会展示出张量元素。
|
||||
|
||||
要想看到张量元素,需要像下面这样,运行一个会话:
|
||||
```
|
||||
import numpy as np
|
||||
|
||||
import tensorflow as tf
|
||||
|
||||
arr = np.array([1, 5.5, 3, 15, 20])
|
||||
|
||||
tensor = tf.convert_to_tensor(arr,tf.float64)
|
||||
|
||||
sess = tf.Session()
|
||||
|
||||
print(sess.run(tensor))
|
||||
|
||||
print(sess.run(tensor[1]))
|
||||
|
||||
```
|
||||
|
||||
## 定义二维张量
|
||||
|
||||
定义二维张量,其方法和定义一维张量是一样的,但要这样来定义数组:
|
||||
|
||||
```
|
||||
arr = np.array([(1, 5.5, 3, 15, 20),(10, 20, 30, 40, 50), (60, 70, 80, 90, 100)])
|
||||
```
|
||||
|
||||
接着转化为张量:
|
||||
```
|
||||
import numpy as np
|
||||
|
||||
import tensorflow as tf
|
||||
|
||||
arr = np.array([(1, 5.5, 3, 15, 20),(10, 20, 30, 40, 50), (60, 70, 80, 90, 100)])
|
||||
|
||||
tensor = tf.convert_to_tensor(arr)
|
||||
|
||||
sess = tf.Session()
|
||||
|
||||
print(sess.run(tensor))
|
||||
|
||||
```
|
||||
|
||||
现在你应该知道怎么定义张量了,那么,怎么在张量之间跑数学运算呢?
|
||||
|
||||
## 在张量上进行数学运算
|
||||
|
||||
假设我们有以下两个数组:
|
||||
```
|
||||
arr1 = np.array([(1,2,3),(4,5,6)])
|
||||
|
||||
arr2 = np.array([(7,8,9),(10,11,12)])
|
||||
|
||||
```
|
||||
|
||||
利用 TenserFlow ,你能做许多数学运算。现在我们需要对这两个数组求和。
|
||||
|
||||
使用加法函数来求和:
|
||||
```
|
||||
import numpy as np
|
||||
|
||||
import tensorflow as tf
|
||||
|
||||
arr1 = np.array([(1,2,3),(4,5,6)])
|
||||
|
||||
arr2 = np.array([(7,8,9),(10,11,12)])
|
||||
|
||||
arr3 = tf.add(arr1,arr2)
|
||||
|
||||
sess = tf.Session()
|
||||
|
||||
tensor = sess.run(arr3)
|
||||
|
||||
print(tensor)
|
||||
|
||||
```
|
||||
|
||||
也可以把数组相乘:
|
||||
```
|
||||
import numpy as np
|
||||
|
||||
import tensorflow as tf
|
||||
|
||||
arr1 = np.array([(1,2,3),(4,5,6)])
|
||||
|
||||
arr2 = np.array([(7,8,9),(10,11,12)])
|
||||
|
||||
arr3 = tf.multiply(arr1,arr2)
|
||||
|
||||
sess = tf.Session()
|
||||
|
||||
tensor = sess.run(arr3)
|
||||
|
||||
print(tensor)
|
||||
|
||||
```
|
||||
|
||||
现在你知道了吧。
|
||||
|
||||
## 三维张量
|
||||
|
||||
我们已经知道了怎么使用一维张量和二维张量,现在,来看一下三维张量吧,不过这次我们不用数字了,而是用一张 RGB 图片。在这张图片上,每一块像素都由 x,y,z 组合表示。
|
||||
|
||||
这些组合形成了图片的宽度、高度以及颜色深度。
|
||||
|
||||
首先使用 matplotlib 库导入一张图片。如果你的系统中没有 matplotlib ,可以 [使用pip][2]来安装它。
|
||||
|
||||
将图片放在 Python 文件的同一目录下,接着使用 matplotlib 导入图片:
|
||||
```
|
||||
import matplotlib.image as img
|
||||
|
||||
myfile = "likegeeks.png"
|
||||
|
||||
myimage = img.imread(myfile)
|
||||
|
||||
print(myimage.ndim)
|
||||
|
||||
print(myimage.shape)
|
||||
|
||||
```
|
||||
|
||||
从运行结果中,你应该能看到,这张三维图片的宽为 150 、高为 150 、颜色深度为 3 。
|
||||
|
||||
你还可以查看这张图片:
|
||||
```
|
||||
import matplotlib.image as img
|
||||
|
||||
import matplotlib.pyplot as plot
|
||||
|
||||
myfile = "likegeeks.png"
|
||||
|
||||
myimage = img.imread(myfile)
|
||||
|
||||
plot.imshow(myimage)
|
||||
|
||||
plot.show()
|
||||
|
||||
```
|
||||
|
||||
真酷!
|
||||
|
||||
那怎么使用 TensorFlow 处理图片呢?超级容易。
|
||||
|
||||
## 使用 TensorFlow 生成或裁剪图片
|
||||
|
||||
首先,向一个占位符赋值:
|
||||
```
|
||||
myimage = tf.placeholder("int32",[None,None,3])
|
||||
|
||||
```
|
||||
|
||||
使用裁剪操作来裁剪图像:
|
||||
```
|
||||
cropped = tf.slice(myimage,[10,0,0],[16,-1,-1])
|
||||
|
||||
```
|
||||
|
||||
最后,运行这个会话:
|
||||
```
|
||||
result = sess.run(cropped, feed\_dict={slice: myimage})
|
||||
|
||||
```
|
||||
|
||||
然后,你就能看到使用 matplotlib 处理过的图像了。
|
||||
|
||||
这是整段代码:
|
||||
```
|
||||
import tensorflow as tf
|
||||
|
||||
import matplotlib.image as img
|
||||
|
||||
import matplotlib.pyplot as plot
|
||||
|
||||
myfile = "likegeeks.png"
|
||||
|
||||
myimage = img.imread(myfile)
|
||||
|
||||
slice = tf.placeholder("int32",[None,None,3])
|
||||
|
||||
cropped = tf.slice(myimage,[10,0,0],[16,-1,-1])
|
||||
|
||||
sess = tf.Session()
|
||||
|
||||
result = sess.run(cropped, feed_dict={slice: myimage})
|
||||
|
||||
plot.imshow(result)
|
||||
|
||||
plot.show()
|
||||
|
||||
```
|
||||
|
||||
是不是很神奇?
|
||||
|
||||
## 使用 TensorFlow 改变图像
|
||||
|
||||
在本例中,我们会使用 TensorFlow 做一下简单的转换。
|
||||
|
||||
首先,指定待处理的图像,并初始化 TensorFlow 变量值:
|
||||
```
|
||||
myfile = "likegeeks.png"
|
||||
|
||||
myimage = img.imread(myfile)
|
||||
|
||||
image = tf.Variable(myimage,name='image')
|
||||
|
||||
vars = tf.global_variables_initializer()
|
||||
|
||||
```
|
||||
|
||||
然后调用 transpose 函数转换,这个函数用来翻转输入网格的 0 轴和 1 轴。
|
||||
```
|
||||
sess = tf.Session()
|
||||
|
||||
flipped = tf.transpose(image, perm=[1,0,2])
|
||||
|
||||
sess.run(vars)
|
||||
|
||||
result=sess.run(flipped)
|
||||
|
||||
```
|
||||
|
||||
接着你就能看到使用 matplotlib 处理过的图像了。
|
||||
```
|
||||
import tensorflow as tf
|
||||
|
||||
import matplotlib.image as img
|
||||
|
||||
import matplotlib.pyplot as plot
|
||||
|
||||
myfile = "likegeeks.png"
|
||||
|
||||
myimage = img.imread(myfile)
|
||||
|
||||
image = tf.Variable(myimage,name='image')
|
||||
|
||||
vars = tf.global_variables_initializer()
|
||||
|
||||
sess = tf.Session()
|
||||
|
||||
flipped = tf.transpose(image, perm=[1,0,2])
|
||||
|
||||
sess.run(vars)
|
||||
|
||||
result=sess.run(flipped)
|
||||
|
||||
plot.imshow(result)
|
||||
|
||||
plot.show()
|
||||
|
||||
```
|
||||
|
||||
以上例子都向你表明了使用 TensorFlow 有多么容易。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.codementor.io/likegeeks/define-and-use-tensors-using-simple-tensorflow-examples-ggdgwoy4u
|
||||
|
||||
作者:[LikeGeeks][a]
|
||||
译者:[ghsgz](https://github.com/ghsgz)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://www.codementor.io/likegeeks
|
||||
[1]:https://likegeeks.com/python-list-functions/
|
||||
[2]:https://likegeeks.com/import-create-install-reload-alias-python-modules/#Install-Python-Modules-Using-pip
|
@ -0,0 +1,187 @@
|
||||
Python全局,局部和非局部变量(带示例)
|
||||
======
|
||||
|
||||
### 全局变量
|
||||
|
||||
在Python中,在函数之外或在全局范围内声明的变量被称为全局变量。 这意味着,全局变量可以在函数内部或外部访问。
|
||||
|
||||
我们来看一个关于如何在Python中创建一个全局变量的示例。
|
||||
|
||||
#### 示例1:创建全局变量
|
||||
```python
|
||||
x = "global"
|
||||
|
||||
def foo():
|
||||
print("x inside :", x)
|
||||
|
||||
foo()
|
||||
print("x outside:", x)
|
||||
```
|
||||
|
||||
当我们运行代码时,将会输出:
|
||||
```
|
||||
x inside : global
|
||||
x outside: global
|
||||
```
|
||||
|
||||
在上面的代码中,我们创建了x作为全局变量,并定义了一个`foo()`来打印全局变量x。 最后,我们调用`foo()`来打印x的值。
|
||||
|
||||
倘若你想改变一个函数内的x的值该怎么办?
|
||||
|
||||
```python
|
||||
x = "global"
|
||||
|
||||
def foo():
|
||||
x = x * 2
|
||||
print(x)
|
||||
foo()
|
||||
```
|
||||
|
||||
当我们运行代码时,将会输出:
|
||||
```
|
||||
UnboundLocalError: local variable 'x' referenced before assignment
|
||||
```
|
||||
|
||||
输出显示一个错误,因为Python将x视为局部变量,x也没有`foo()`内部定义。
|
||||
|
||||
为了运行正常,我们使用`global`关键字,访问[PythonGlobal关键字][1]以便了解更多。
|
||||
|
||||
### 局部变量
|
||||
|
||||
在函数体内或局部作用域内声明的变量称为局部变量。
|
||||
|
||||
#### 示例2:访问作用域外的局部变量
|
||||
|
||||
```python
|
||||
def foo():
|
||||
y = "local"
|
||||
|
||||
foo()
|
||||
print(y)
|
||||
```
|
||||
|
||||
当我们运行代码时,将会输出:
|
||||
```
|
||||
NameError: name 'y' is not defined
|
||||
```
|
||||
|
||||
输出显示了一个错误,因为我们试图在全局范围内访问局部变量y,而局部变量只能在`foo() `函数内部或局部作用域内有效。
|
||||
|
||||
我们来看一个关于如何在Python中创建一个局部变量的例子。
|
||||
|
||||
#### 示例3:创建一个局部变量
|
||||
|
||||
通常,我们在函数内声明一个变量来创建一个局部变量。
|
||||
```python
|
||||
def foo():
|
||||
y = "local"
|
||||
print(y)
|
||||
|
||||
foo()
|
||||
```
|
||||
|
||||
当我们运行代码时,将会输出:
|
||||
```
|
||||
local
|
||||
```
|
||||
|
||||
让我们来看看前面的问题,其中x是一个全局变量,我们想修改`foo()`内部的x。
|
||||
|
||||
### 全局变量和局部变量
|
||||
|
||||
在这里,我们将展示如何在同一份代码中使用全局变量和局部变量。
|
||||
|
||||
#### 示例4:在同一份代码中使用全局变量和局部变量
|
||||
```python
|
||||
x = "global"
|
||||
|
||||
def foo():
|
||||
global x
|
||||
y = "local"
|
||||
x = x * 2
|
||||
print(x)
|
||||
print(y)
|
||||
|
||||
foo()
|
||||
```
|
||||
|
||||
当我们运行代码时,将会输出(译者注:原文中输出结果的两个global有空格,正确的是没有空格):
|
||||
```
|
||||
globalglobal
|
||||
local
|
||||
```
|
||||
|
||||
在上面的代码中,我们将x声明为全局变量,将y声明为`foo()`中的局部变量。 然后,我们使用乘法运算符`*`来修改全局变量x,并打印x和y。
|
||||
|
||||
在调用`foo()`之后,x的值变成`globalglobal`了(译者注:原文同样有空格,正确的是没有空格),因为我们使用`x * 2`打印两次`global`。 之后,我们打印局部变量y的值,即`local`。
|
||||
|
||||
#### 示例5:具有相同名称的全局变量和局部变量
|
||||
```python
|
||||
x = 5
|
||||
|
||||
def foo():
|
||||
x = 10
|
||||
print("local x:", x)
|
||||
|
||||
foo()
|
||||
print("global x:", x)
|
||||
```
|
||||
|
||||
当我们运行代码时,将会输出:
|
||||
```
|
||||
local x: 10
|
||||
global x: 5
|
||||
```
|
||||
|
||||
在上面的代码中,我们对全局变量和局部变量使用了相同的名称x。 当我们打印相同的变量时却得到了不同的结果,因为这两个作用域内都声明了变量,即`foo()`内部的局部作用域和`foo()`外面的全局作用域。
|
||||
|
||||
当我们在`foo()`内部打印变量时,它输出`local x: 10`,这被称为变量的局部作用域。
|
||||
|
||||
同样,当我们在`foo()`外部打印变量时,它输出`global x: 5`,这被称为变量的全局作用域。
|
||||
|
||||
### 非局部变量
|
||||
|
||||
非局部变量用于局部作用域未定义的嵌套函数。 这意味着,变量既不能在局部也不能在全局范围内。
|
||||
|
||||
我们来看一个关于如何在Python中创建一个非局部变量的例子。(译者注:原文为创建全局变量,疑为笔误)
|
||||
|
||||
我们使用`nonlocal`关键字来创建非局部变量。
|
||||
|
||||
#### 例6:创建一个非局部变量
|
||||
```python
|
||||
def outer():
|
||||
x = "local"
|
||||
|
||||
def inner():
|
||||
nonlocal x
|
||||
x = "nonlocal"
|
||||
print("inner:", x)
|
||||
|
||||
inner()
|
||||
print("outer:", x)
|
||||
|
||||
outer()
|
||||
```
|
||||
|
||||
当我们运行代码时,将会输出:
|
||||
```
|
||||
inner: nonlocal
|
||||
outer: nonlocal
|
||||
```
|
||||
|
||||
在上面的代码中有一个嵌套函数`inner()`。 我们使用`nonlocal`关键字来创建非局部变量。`inner()`函数是在另一个函数`outer()`的作用域中定义的。
|
||||
|
||||
注意:如果我们改变非局部变量的值,那么变化就会出现在局部变量中。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.programiz.com/python-programming/global-local-nonlocal-variables
|
||||
|
||||
作者:[programiz][a]
|
||||
译者:[Flowsnow](https://github.com/Flowsnow)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://www.programiz.com/
|
||||
[1]:https://www.programiz.com/python-programming/global-keyword
|
Loading…
Reference in New Issue
Block a user