mirror of
https://github.com/iiab/iiab.git
synced 2025-02-12 11:12:06 +00:00
initial checkin -- May 27, 2017
This commit is contained in:
commit
845632d0ac
488 changed files with 41559 additions and 0 deletions
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
xs-config.spec
|
||||
build
|
||||
deprecated
|
||||
.patches
|
339
COPYING
Normal file
339
COPYING
Normal file
|
@ -0,0 +1,339 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
16
LICENSE
Normal file
16
LICENSE
Normal file
|
@ -0,0 +1,16 @@
|
|||
COPYRIGHT and LICENSE
|
||||
|
||||
Many files in this repository have an explicit copyright notice and terms of license in the file.
|
||||
|
||||
Authors contributing to this repository are encouraged to provide a copyright notice and to license their work
|
||||
under the terms of the GNU Library General Public License as published by the Free Software Foundation;
|
||||
either version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This license is contained in the file named COPYING. The simplest way to do this is to include
|
||||
the following two lines at the top of the file:
|
||||
|
||||
# Copyright (C) 20xx <your name>
|
||||
# Licensed under the terms of the GNU GPL v2 or later; see COPYING for details.
|
||||
|
||||
All files not containing an explicit copyright notice or terms of license in the file are Copyright © 2015, Unleash Kids,
|
||||
and are licensed under the terms of the GPLv2 license in the file named COPYING in the root of the repository.
|
41
README.rst
Normal file
41
README.rst
Normal file
|
@ -0,0 +1,41 @@
|
|||
======================================
|
||||
School Server Community Edition (XSCE)
|
||||
======================================
|
||||
|
||||
Welcome to the Git repository of the XSCE project. XSCE is a community-based
|
||||
project developed and supported by volunteers from around the world. It
|
||||
provides communication, networking, content, and maintenance to schools and
|
||||
classrooms. In everyday usage the school server provides services which extend
|
||||
capabilities of the connected laptops while being transparent to the
|
||||
user. These services include:
|
||||
|
||||
* Classroom connectivity – Similar to what you would find in an advanced home router.
|
||||
* Internet gateway – If available, an internet connection is made available to laptops.
|
||||
* Content – Tools to make instructional media available to their schools and classrooms.
|
||||
* Maintenance – Tools to keep laptop updated and running smoothly.
|
||||
|
||||
All of our server code resides in this repository. We are using ansible_ as the
|
||||
underlying technology to install, deploy, configure and manage the various
|
||||
server components.
|
||||
|
||||
Documentation has recently moved to the wiki of this repo
|
||||
|
||||
Please see the `XSCE wiki`_
|
||||
|
||||
Installation procedures are in the process of being reworked to include:
|
||||
|
||||
* Offline install on bare metal from a usb stick
|
||||
* Offline install with an iso file
|
||||
* Manual install of all or part of the server in combination with either of the above
|
||||
|
||||
Full installation instructions are in the wiki of this repo:
|
||||
|
||||
Please read the `installation`_ documentation.
|
||||
|
||||
See the `XSCE project`_ for more information about the project.
|
||||
|
||||
.. _XSCE wiki: https://github.com/XSCE/xsce/wiki
|
||||
.. _installation: https://github.com/XSCE/xsce/wiki/XSCE-Installation
|
||||
.. _ansible: http://www.ansibleworks.com/
|
||||
.. _ansible documentation: http://www.ansibleworks.com/docs/
|
||||
.. _XSCE project: http://schoolserver.org/
|
53
ReleaseNotes6.0.md
Normal file
53
ReleaseNotes6.0.md
Normal file
|
@ -0,0 +1,53 @@
|
|||
# Release Notes for XSCE 6.0
|
||||
|
||||
## What is it?
|
||||
|
||||
XSCE is the digital backbone for your education revolution. Put simply, School Server is an open-education project inspired by
|
||||
One Laptop Per Child to provide breakthrough digital learning tools to the world’s poorest children.
|
||||
|
||||
### A Rose by any other Name
|
||||
|
||||
Internally and in the source code we refer to this software as XSCE, the Community Edition of the XS server originally from
|
||||
OLPC. Students and teachers often know it as Internet in a Box, a collection of educational materials and applications found on the internet,
|
||||
but available on the server even without an internet connection. We also refer to it as a School Server since it is aimed at
|
||||
schools and other places where people learn and performs the function of a server.
|
||||
|
||||
## What's new in XSCE Release 6.0?
|
||||
|
||||
This release extends the tools available to educators in three ways:
|
||||
|
||||
* It makes available free and open source content that is available in many languages
|
||||
* It provides new avenues for students to create, and share their work
|
||||
* It contains number of advances to permit easy configuration, tailoring of content, and monitoring of student work.
|
||||
|
||||
### Newly Available Open Source Educational Content
|
||||
|
||||
|
||||
* KA Lite brings the online features of **Khan Academy** to the **offline** schoolserver based classroom. There are videos, exercises, tests, and student tracking in a number of languages, all selectable via a Graphical User Interface. https://learningequality.org/ka-lite/
|
||||
* Searchable **offline** access to **Wikipedia** and other content such as Wiktionaries and TED Talks in a variety of subjects and many languages, provided by the **Kiwix server** technology. http://www.kiwix.org/wiki/Main_Page
|
||||
* RACHEL (a currated selection of offline materials) http://worldpossible.org/rachel/
|
||||
* Bring your **own content** by inserting a **USB thumbdrive** with content into the server having it immediately viewable by students.
|
||||
|
||||
### Encourage Students to Write, Foster the Creative Process
|
||||
|
||||
* Elgg provides the tools for generating social networks http://learn.elgg.org/en/2.0/intro/features.html
|
||||
* ownCloud provides client based tools for storing and retrieving materials stored on the XSCE local cloud.
|
||||
* DokuWiki (EXPERIMENTAL) provides a means for students to publish their work. https://www.dokuwiki.org/features
|
||||
* Wordpress (EXPERIMENTAL -- enable in "local_vars") gives students experience editing/sharing using a tool that is becoming an industry standard.
|
||||
|
||||
### New Tools for Administering the XSCE schoolserver
|
||||
|
||||
* A new Graphical User Interface (Admin Console) to enable services, select and download content, get information
|
||||
* AWstats is a flexible tool for summarizing the web traffic on and through the server in graphical and detailed ways. http://www.awstats.org/
|
||||
|
||||
## How do I get it?
|
||||
|
||||
There are three main methods of installing this software:
|
||||
|
||||
* Use ansible and the git repository - this is the fall back when you need to customize or you have a platform for which we have not created an image.
|
||||
* Use an image you download - for some commonly used platforms we create image files that you can download, put on a usb stick or sd card and boot in your new hardware.
|
||||
* Create and use your own image - this will appeal to you if you want an image to use in multiple machines and are able to use the tools we provide to create it.
|
||||
|
||||
In each case you need hardware that has been assembled, but with nothing installed on it.
|
||||
|
||||
Detailed instructions on each of these methods is at https://github.com/XSCE/xsce/wiki/XSCE-Installation.
|
36
ReleaseNotes6.1.md
Normal file
36
ReleaseNotes6.1.md
Normal file
|
@ -0,0 +1,36 @@
|
|||
# Release Notes for Release 6.1
|
||||
**What's New?**
|
||||
|
||||
* Calibre -- A tool for managing a library of eBooks, modifyiing their file formats, adding search terms, and making them availabe online.
|
||||
* Wordpress -- A content management system which gives students experience with editing wiki pages, blogs, menuing systems, and which is widely used.
|
||||
* Dokuwiki -- An alternate wiki system, similar to wordpress, but less popular, which makes transferring wiki materials easy from one school server to another.
|
||||
* Sugarizer -- Makes some of the sugar activities available to browser clients on laptops, and smart phones/tablets.
|
||||
* CUPS -- Common Unix Printing System provides the ability to connect to and share network or USB connected printers.
|
||||
|
||||
**What's Upgraded?**
|
||||
|
||||
* Moodle is now upgraded to version 3.1, the most recent (long term support) version that will be supported until May 2019.
|
||||
* Elgg -- A social networking application is upgraded to 2.1.
|
||||
* Owncloud -- Permits sharing of all kinds of content between clients of a local server that is not internet connected (version 9).
|
||||
|
||||
**Do all these new Services Slow my Server down?**
|
||||
|
||||
A service that is installed on your hard disk, but not enabled in the administrative console, will have no impact on computer speed (will not use cpu cycles, or occupy scarce memory resources). The XSCE default is to install everything, and only enable the few things which are essential for a server to operate.
|
||||
|
||||
If you want to enable a service, you must browse to http://schoolserver.lan/admin, and click on configure, services enabled, and the appropriate checkbox. In addition, many services require additional content to be downloaded, which can also be accomplished by selecting the "Install Content" header button.
|
||||
|
||||
**How Do I Install 6.1?**
|
||||
|
||||
The install instructions have not changed much since release-6.0. Please refer to https://github.com/XSCE/xsce/wiki/XSCE-Installation for the overall process -- Noting the following:
|
||||
|
||||
* On FC22, add "yum" to the installs prior to running the ansible playbook i.e.
|
||||
```
|
||||
yum install -y git yum ansible1.9
|
||||
cd /opt
|
||||
mkdir /opt/schoolserver
|
||||
cd schoolserver
|
||||
git clone https://github.com/XSCE/xsce --branch release-6.1 --depth 1
|
||||
cd xsce
|
||||
./install-console
|
||||
```
|
||||
|
193
ansible.cfg
Normal file
193
ansible.cfg
Normal file
|
@ -0,0 +1,193 @@
|
|||
# config file for ansible -- http://ansible.com/
|
||||
# ==============================================
|
||||
|
||||
# nearly all parameters can be overridden in ansible-playbook
|
||||
# or with command line flags. ansible will read ANSIBLE_CONFIG,
|
||||
# ansible.cfg in the current working directory, .ansible.cfg in
|
||||
# the home directory or /etc/ansible/ansible.cfg, whichever it
|
||||
# finds first
|
||||
|
||||
[defaults]
|
||||
|
||||
# some basic default values...
|
||||
|
||||
hostfile = /etc/ansible/hosts
|
||||
library = /usr/share/ansible
|
||||
remote_tmp = $HOME/.ansible/tmp
|
||||
pattern = *
|
||||
forks = 5
|
||||
poll_interval = 15
|
||||
sudo_user = root
|
||||
#ask_sudo_pass = True
|
||||
#ask_pass = True
|
||||
transport = smart
|
||||
remote_port = 22
|
||||
module_lang = C
|
||||
|
||||
# plays will gather facts by default, which contain information about
|
||||
# the remote system.
|
||||
#
|
||||
# smart - gather by default, but don't regather if already gathered
|
||||
# implicit - gather by default, turn off with gather_facts: False
|
||||
# explicit - do not gather by default, must say gather_facts: True
|
||||
gathering = implicit
|
||||
|
||||
# additional paths to search for roles in, colon separated
|
||||
#roles_path = /etc/ansible/roles
|
||||
|
||||
# uncomment this to disable SSH key host checking
|
||||
#host_key_checking = False
|
||||
|
||||
# change this for alternative sudo implementations
|
||||
sudo_exe = sudo
|
||||
|
||||
# what flags to pass to sudo
|
||||
#sudo_flags = -H
|
||||
|
||||
# SSH timeout
|
||||
timeout = 10
|
||||
|
||||
# default user to use for playbooks if user is not specified
|
||||
# (/usr/bin/ansible will use current user as default)
|
||||
#remote_user = root
|
||||
|
||||
# logging is off by default unless this path is defined
|
||||
# if so defined, consider logrotate
|
||||
#log_path = /var/log/ansible.log
|
||||
|
||||
# default module name for /usr/bin/ansible
|
||||
#module_name = command
|
||||
|
||||
# use this shell for commands executed under sudo
|
||||
# you may need to change this to bin/bash in rare instances
|
||||
# if sudo is constrained
|
||||
#executable = /bin/sh
|
||||
|
||||
# if inventory variables overlap, does the higher precedence one win
|
||||
# or are hash values merged together? The default is 'replace' but
|
||||
# this can also be set to 'merge'.
|
||||
#hash_behaviour = replace
|
||||
|
||||
# list any Jinja2 extensions to enable here:
|
||||
#jinja2_extensions = jinja2.ext.do,jinja2.ext.i18n
|
||||
|
||||
# if set, always use this private key file for authentication, same as
|
||||
# if passing --private-key to ansible or ansible-playbook
|
||||
#private_key_file = /path/to/file
|
||||
|
||||
# format of string {{ ansible_managed }} available within Jinja2
|
||||
# templates indicates to users editing templates files will be replaced.
|
||||
# replacing {file}, {host} and {uid} and strftime codes with proper values.
|
||||
ansible_managed = Ansible managed: {file} modified on %Y-%m-%d %H:%M:%S by {uid} on {host}
|
||||
|
||||
# by default, ansible-playbook will display "Skipping [host]" if it determines a task
|
||||
# should not be run on a host. Set this to "False" if you don't want to see these "Skipping"
|
||||
# messages. NOTE: the task header will still be shown regardless of whether or not the
|
||||
# task is skipped.
|
||||
#display_skipped_hosts = True
|
||||
|
||||
# by default (as of 1.3), Ansible will raise errors when attempting to dereference
|
||||
# Jinja2 variables that are not set in templates or action lines. Uncomment this line
|
||||
# to revert the behavior to pre-1.3.
|
||||
#error_on_undefined_vars = False
|
||||
|
||||
# by default (as of 1.6), Ansible may display warnings based on the configuration of the
|
||||
# system running ansible itself. This may include warnings about 3rd party packages or
|
||||
# other conditions that should be resolved if possible.
|
||||
# to disable these warnings, set the following value to False:
|
||||
system_warnings = False
|
||||
|
||||
# by default (as of 1.4), Ansible may display deprecation warnings for language
|
||||
# features that should no longer be used and will be removed in future versions.
|
||||
# to disable these warnings, set the following value to False:
|
||||
deprecation_warnings = False
|
||||
|
||||
# set plugin path directories here, separate with colons
|
||||
action_plugins = /usr/share/ansible_plugins/action_plugins
|
||||
callback_plugins = /usr/share/ansible_plugins/callback_plugins
|
||||
connection_plugins = /usr/share/ansible_plugins/connection_plugins
|
||||
lookup_plugins = /usr/share/ansible_plugins/lookup_plugins
|
||||
vars_plugins = /usr/share/ansible_plugins/vars_plugins
|
||||
filter_plugins = /usr/share/ansible_plugins/filter_plugins
|
||||
|
||||
# don't like cows? that's unfortunate.
|
||||
# set to 1 if you don't want cowsay support or export ANSIBLE_NOCOWS=1
|
||||
#nocows = 1
|
||||
|
||||
# don't like colors either?
|
||||
# set to 1 if you don't want colors, or export ANSIBLE_NOCOLOR=1
|
||||
#nocolor = 1
|
||||
|
||||
# the CA certificate path used for validating SSL certs. This path
|
||||
# should exist on the controlling node, not the target nodes
|
||||
# common locations:
|
||||
# RHEL/CentOS: /etc/pki/tls/certs/ca-bundle.crt
|
||||
# Fedora : /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem
|
||||
# Ubuntu : /usr/share/ca-certificates/cacert.org/cacert.org.crt
|
||||
#ca_file_path =
|
||||
|
||||
# the http user-agent string to use when fetching urls. Some web server
|
||||
# operators block the default urllib user agent as it is frequently used
|
||||
# by malicious attacks/scripts, so we set it to something unique to
|
||||
# avoid issues.
|
||||
#http_user_agent = ansible-agent
|
||||
|
||||
[paramiko_connection]
|
||||
|
||||
# uncomment this line to cause the paramiko connection plugin to not record new host
|
||||
# keys encountered. Increases performance on new host additions. Setting works independently of the
|
||||
# host key checking setting above.
|
||||
#record_host_keys=False
|
||||
|
||||
# by default, Ansible requests a pseudo-terminal for commands executed under sudo. Uncomment this
|
||||
# line to disable this behaviour.
|
||||
#pty=False
|
||||
|
||||
[ssh_connection]
|
||||
|
||||
# ssh arguments to use
|
||||
# Leaving off ControlPersist will result in poor performance, so use
|
||||
# paramiko on older platforms rather than removing it
|
||||
#ssh_args = -o ControlMaster=auto -o ControlPersist=60s
|
||||
|
||||
# The path to use for the ControlPath sockets. This defaults to
|
||||
# "%(directory)s/ansible-ssh-%%h-%%p-%%r", however on some systems with
|
||||
# very long hostnames or very long path names (caused by long user names or
|
||||
# deeply nested home directories) this can exceed the character limit on
|
||||
# file socket names (108 characters for most platforms). In that case, you
|
||||
# may wish to shorten the string below.
|
||||
#
|
||||
# Example:
|
||||
# control_path = %(directory)s/%%h-%%r
|
||||
#control_path = %(directory)s/ansible-ssh-%%h-%%p-%%r
|
||||
|
||||
# Enabling pipelining reduces the number of SSH operations required to
|
||||
# execute a module on the remote server. This can result in a significant
|
||||
# performance improvement when enabled, however when using "sudo:" you must
|
||||
# first disable 'requiretty' in /etc/sudoers
|
||||
#
|
||||
# By default, this option is disabled to preserve compatibility with
|
||||
# sudoers configurations that have requiretty (the default on many distros).
|
||||
#
|
||||
#pipelining = False
|
||||
|
||||
# if True, make ansible use scp if the connection type is ssh
|
||||
# (default is sftp)
|
||||
#scp_if_ssh = True
|
||||
|
||||
[accelerate]
|
||||
accelerate_port = 5099
|
||||
accelerate_timeout = 30
|
||||
accelerate_connect_timeout = 5.0
|
||||
|
||||
# The daemon timeout is measured in minutes. This time is measured
|
||||
# from the last activity to the accelerate daemon.
|
||||
accelerate_daemon_timeout = 30
|
||||
|
||||
# If set to yes, accelerate_multi_key will allow multiple
|
||||
# private keys to be uploaded to it, though each user must
|
||||
# have access to the system via SSH to add a new key. The default
|
||||
# is "no".
|
||||
#accelerate_multi_key = yes
|
||||
|
||||
command_warnings = False
|
3
ansible_hosts
Normal file
3
ansible_hosts
Normal file
|
@ -0,0 +1,3 @@
|
|||
[localhost]
|
||||
127.0.0.1
|
||||
|
51
install-console
Executable file
51
install-console
Executable file
|
@ -0,0 +1,51 @@
|
|||
#!/bin/bash
|
||||
|
||||
# copy var files to /etc/xsce for subsequent use
|
||||
|
||||
#./install-init
|
||||
|
||||
# if not the first run, repo location is here
|
||||
|
||||
if [ -f /etc/xsce/xsce.env ]
|
||||
then
|
||||
. /etc/xsce/xsce.env
|
||||
cd $XSCE_DIR
|
||||
else
|
||||
XSCE_DIR=/opt/schoolserver/xsce
|
||||
mkdir -p /etc/xsce
|
||||
touch /etc/xsce/config_vars.yml
|
||||
fi
|
||||
|
||||
# don't track vars/local_vars.yml
|
||||
git update-index --assume-unchanged vars/local_vars.yml
|
||||
|
||||
PLAYBOOK="xsce-base.yml"
|
||||
INVENTORY="ansible_hosts"
|
||||
SELINUX_BEFORE=""
|
||||
SELINUX_AFTER=""
|
||||
|
||||
if [ ! -f $PLAYBOOK ]
|
||||
then
|
||||
echo "XSCE Playbook not found."
|
||||
echo "Please run this command from the top level of the git repo."
|
||||
echo "Exiting."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -f /etc/selinux/config ]
|
||||
then
|
||||
SELINUX_BEFORE=`cat /etc/selinux/config | gawk -F= '/^SELINUX=/{ print $2 }'`
|
||||
fi
|
||||
|
||||
export ANSIBLE_LOG_PATH="$XSCE_DIR/xsce-install.log"
|
||||
ansible-playbook -i $INVENTORY $PLAYBOOK --connection=local
|
||||
|
||||
if [ -f /etc/selinux/config ]
|
||||
then
|
||||
SELINUX_AFTER=`cat /etc/selinux/config | gawk -F= '/^SELINUX=/{ print $2 }'`
|
||||
fi
|
||||
|
||||
if [ "$SELINUX_BEFORE" != "$SELINUX_AFTER" ]; then
|
||||
echo "Rebooting ..."
|
||||
reboot
|
||||
fi
|
6
roles/1-prep/README.rst
Normal file
6
roles/1-prep/README.rst
Normal file
|
@ -0,0 +1,6 @@
|
|||
===========
|
||||
Prep README
|
||||
===========
|
||||
|
||||
This role is a sort on init or startup. It includes preliminaries like hostname and is where things
|
||||
that are specific to a particular platform, such as the XO, are done before the bulk of the install.
|
57
roles/1-prep/defaults/main.yml
Normal file
57
roles/1-prep/defaults/main.yml
Normal file
|
@ -0,0 +1,57 @@
|
|||
# use these as a tag a release at a point in time
|
||||
xsce_base_ver: 0
|
||||
gui_version: 2
|
||||
NUC6_firmware_needed: False
|
||||
|
||||
# These entries should never be changed in this file.
|
||||
# These are defaults for boolean routines,
|
||||
installing: False
|
||||
exFAT_enabled: False
|
||||
no_NM_reload: False
|
||||
has_WAN: False
|
||||
wireless_lan_present: False
|
||||
udev_needs_patch: False
|
||||
strict_networking: False
|
||||
xsce_demo_mode: False
|
||||
gw_active: False
|
||||
gui_static_wan: False
|
||||
has_internet_connection: False
|
||||
is_F18: False
|
||||
is_F20: False
|
||||
is_F21: False
|
||||
is_F22: False
|
||||
is_F23: False
|
||||
is_F24: False
|
||||
|
||||
# Set default for discovered hardware
|
||||
driver_name: nl80211
|
||||
rpi_model: none
|
||||
is_rpi: False
|
||||
xo_model: none
|
||||
rtc_id: none
|
||||
|
||||
# Set defaults for discovery process as strings
|
||||
wifi1: "not found-1"
|
||||
wifi2: "not found-2"
|
||||
discovered_wan_iface: "none"
|
||||
discovered_lan_iface: "none"
|
||||
discovered_wireless_iface: "none"
|
||||
xsce_wireless_lan_iface: "none"
|
||||
xsce_lan_iface: "none"
|
||||
xsce_wan_iface: "none"
|
||||
device_gw: "none"
|
||||
has_ifcfg_gw: "none"
|
||||
has_wifi_gw: "none"
|
||||
ap_device: "none"
|
||||
device_gw2: ""
|
||||
|
||||
# WiFi
|
||||
ssid: XSCE
|
||||
hostapd_wait: 10
|
||||
gui_port: 80
|
||||
|
||||
# must keep roles/xsce-admin/defaults/main.yml sync'd
|
||||
admin_console_path: "{{ xsce_base }}/admin_console"
|
||||
cmdsrv_path: "{{ xsce_base }}/xsce_cmdsrv"
|
||||
xsce_cmdsrv_dbname : "xsce_cmdsrv.0.2.db"
|
||||
wifi_id: none
|
162
roles/1-prep/tasks/computed_vars.yml
Normal file
162
roles/1-prep/tasks/computed_vars.yml
Normal file
|
@ -0,0 +1,162 @@
|
|||
# get local vars from scripts in /etc/ansible/facts.d
|
||||
# on first run, this will generate UUID
|
||||
|
||||
- name: re-read facts
|
||||
setup: filter=ansible_local
|
||||
|
||||
# set top level variables from local facts for convenience
|
||||
- set_fact:
|
||||
xo_model: '{{ ansible_local["local_facts"]["xo_model"] }}'
|
||||
phplib_dir: '{{ ansible_local["local_facts"]["phplib_dir"] }}'
|
||||
xsce_base_ver: '{{ ansible_local["local_facts"]["xsce_base_ver"] }}'
|
||||
xsce_preload: '{{ ansible_local["local_facts"]["xsce_preload"] }}'
|
||||
|
||||
- name: Defaulting xsce_base_ver
|
||||
set_fact:
|
||||
xsce_base_ver: 0
|
||||
when: xsce_base_ver == ""
|
||||
|
||||
- name: Defaulting xsce_prepped
|
||||
set_fact:
|
||||
xsce_prepped: False
|
||||
tags:
|
||||
- download
|
||||
- download2
|
||||
|
||||
- name: Set exFAT enabled for XOs
|
||||
set_fact:
|
||||
exFAT_enabled: True
|
||||
when: xo_model != "none"
|
||||
|
||||
- name: add version section
|
||||
ini_file: dest='{{ xsce_config_file }}'
|
||||
section=runtime
|
||||
option='{{ item.option }}'
|
||||
value='{{ item.value }}'
|
||||
with_items:
|
||||
- option: 'runtime_branch'
|
||||
value: '{{ ansible_local["local_facts"]["xsce_branch"] }}'
|
||||
- option: 'runtime_commit'
|
||||
value: '{{ ansible_local["local_facts"]["xsce_commit"] }}'
|
||||
- option: 'runtime_date'
|
||||
value: '{{ ansible_date_time["iso8601"] }}'
|
||||
- option: 'runtime_php'
|
||||
value: '{{ phplib_dir }}'
|
||||
- option: 'runtime_preload'
|
||||
value: '{{ xsce_preload }}'
|
||||
- option: 'runtime_base_ver'
|
||||
value: '{{ xsce_base_ver }}'
|
||||
- option: 'kernel'
|
||||
value: '{{ ansible_kernel }}'
|
||||
- option: 'memory_mb'
|
||||
value: '{{ ansible_memtotal_mb }}'
|
||||
- option: 'swap_mb'
|
||||
value: '{{ ansible_swaptotal_mb }}'
|
||||
- option: 'product_id'
|
||||
value: '{{ ansible_product_uuid }}'
|
||||
|
||||
# Put all computed vars here so derive properly from any prior var file
|
||||
- name: Set port 80 for Admin Console
|
||||
set_fact:
|
||||
gui_port: 80
|
||||
when: not adm_cons_force_ssl
|
||||
|
||||
- name: Set port 443 for Admin Console
|
||||
set_fact:
|
||||
gui_port: 443
|
||||
when: adm_cons_force_ssl
|
||||
|
||||
- name: Turn on mysql if elgg or rachel enabled
|
||||
set_fact:
|
||||
mysql_install: True
|
||||
mysql_enabled: True
|
||||
|
||||
# we decided to enable mysql unconditionally
|
||||
# when: elgg_enabled or rachel_enabled or owncloud_enabled or phpmyadmin_enabled or wordpress_enabled or iiab_menu_install
|
||||
|
||||
- name: Turn on mongodb if sugarizer enabled
|
||||
set_fact:
|
||||
mongodb_install: True
|
||||
mongodb_enabled: True
|
||||
when: sugarizer_enabled
|
||||
|
||||
# There might be other db's
|
||||
- name: Turn on postgresql if moodle or pathagar enabled
|
||||
set_fact:
|
||||
postgresql_install: True
|
||||
postgresql_enabled: True
|
||||
when: moodle_enabled or pathagar_enabled
|
||||
|
||||
- name: Turn on docker if schooltool is to be installed
|
||||
set_fact:
|
||||
docker_install: True
|
||||
docker_enabled: True
|
||||
when: schooltool_enabled or schooltool_install
|
||||
|
||||
# for various reasons the mysql service can not be enabled on fedora 20,
|
||||
# but 'mariadb', which is its real name can
|
||||
# on fedora 18 we need to use 'mysqld'
|
||||
|
||||
- name: Set mysqld service name to mariadb by default
|
||||
set_fact:
|
||||
mysql_service: mariadb
|
||||
|
||||
- name: Set mysqld service name to mysqld for fedora 18
|
||||
set_fact:
|
||||
mysql_service: mysqld
|
||||
no_NM_reload: True
|
||||
is_F18: True
|
||||
when: ansible_distribution_release == "based on Fedora 18" or ansible_distribution_version == "18"
|
||||
|
||||
- name: Set mysql service name to mysql for debian
|
||||
set_fact:
|
||||
mysql_service: mysql
|
||||
when: ansible_distribution == "Debian"
|
||||
|
||||
- name: Fedora 20
|
||||
set_fact:
|
||||
is_F20: True
|
||||
when: ansible_distribution == "Fedora" and ansible_distribution_version == "20"
|
||||
|
||||
- name: Fedora 21
|
||||
set_fact:
|
||||
is_F21: True
|
||||
when: ansible_distribution == "Fedora" and ansible_distribution_version == "21"
|
||||
|
||||
- name: Fedora 22
|
||||
set_fact:
|
||||
is_F22: True
|
||||
when: ansible_distribution == "Fedora" and ansible_distribution_version == "22"
|
||||
|
||||
- name: Fedora 23
|
||||
set_fact:
|
||||
is_F23: True
|
||||
when: ansible_distribution == "Fedora" and ansible_distribution_version == "23"
|
||||
|
||||
- name: Fedora 24
|
||||
set_fact:
|
||||
is_F24: True
|
||||
when: ansible_distribution == "Fedora" and ansible_distribution_version == "24"
|
||||
|
||||
- name: CentOS
|
||||
set_fact:
|
||||
is_CentOS: True
|
||||
when: ansible_distribution == "CentOS"
|
||||
|
||||
- name: Set kiwix source file name i686
|
||||
set_fact:
|
||||
kiwix_src_file: "kiwix-linux-i686.tar.bz2"
|
||||
kiwix_src_bin_only: False
|
||||
when: ansible_machine == "i686"
|
||||
|
||||
- name: Set kiwix source file name x86_64
|
||||
set_fact:
|
||||
kiwix_src_file: "kiwix-0.9-linux-x86_64.tar.bz2"
|
||||
kiwix_src_bin_only: False
|
||||
when: ansible_machine == "x86_64"
|
||||
|
||||
- name: Set kiwix source file name armv7l
|
||||
set_fact:
|
||||
kiwix_src_file: "kiwix-server-0.9-linux-armv5tejl.tar.bz2"
|
||||
kiwix_src_bin_only: True
|
||||
when: ansible_machine == "armv7l"
|
305
roles/1-prep/tasks/detected_network.yml
Normal file
305
roles/1-prep/tasks/detected_network.yml
Normal file
|
@ -0,0 +1,305 @@
|
|||
- name: Checking xs_domain_name
|
||||
shell: "cat /etc/sysconfig/xs_domain_name"
|
||||
register: prior_domain
|
||||
ignore_errors: True
|
||||
|
||||
# above always registers
|
||||
- name: Checking for prior domain name
|
||||
set_fact:
|
||||
xsce_domain: "{{ prior_domain.stdout }}"
|
||||
when: prior_domain.stdout != "lan" and prior_domain.stdout != ""
|
||||
|
||||
- name: xs_wan_device
|
||||
shell: "cat /etc/sysconfig/xs_wan_device"
|
||||
register: prior_gw
|
||||
ignore_errors: True
|
||||
|
||||
- name: Checking for old device gateway interface for device test
|
||||
set_fact:
|
||||
device_gw: "{{ prior_gw.stdout }}"
|
||||
device_gw2: "{{ prior_gw.stdout }}"
|
||||
when: prior_gw is defined and prior_gw.stdout != ""
|
||||
|
||||
- name: Checking for ifcfg-WAN file
|
||||
stat: path=/etc/sysconfig/network-scripts/ifcfg-WAN
|
||||
register: has_ifcfg_WAN
|
||||
|
||||
- name: Setting ifcfg-WAN True
|
||||
set_fact:
|
||||
has_WAN: True
|
||||
when: has_ifcfg_WAN.stat.exists
|
||||
|
||||
# DETECT -- gateway and wireless
|
||||
- name: Get a list of slaves from previous config
|
||||
shell: "egrep -rn BRIDGE=br0 /etc/sysconfig/network-scripts/ifcfg-* | gawk -F'[-:]' '{print $3}'"
|
||||
register: ifcfg_slaves
|
||||
ignore_errors: True
|
||||
changed_when: False
|
||||
|
||||
# Discover do we have a gateway? -- if ansible detects gateway, becomes WAN candidate
|
||||
- name: Finding gateway
|
||||
set_fact:
|
||||
discovered_wan_iface: "{{ ansible_default_ipv4.alias }}"
|
||||
when: 'ansible_default_ipv4.gateway is defined'
|
||||
|
||||
- name: Verify gateway present
|
||||
shell: ping -c2 "{{ ansible_default_ipv4.gateway }}" &> /dev/null ; echo $?
|
||||
register: gw_active_test
|
||||
when: discovered_wan_iface != "none"
|
||||
|
||||
- name: Recording gateway response
|
||||
set_fact:
|
||||
gw_active: True
|
||||
when: discovered_wan_iface != "none" and gw_active_test.stdout == "0"
|
||||
|
||||
- name: Test for internet access
|
||||
get_url: url="{{ xsce_download_url }}/heart-beat.txt" dest=/tmp/heart-beat.txt
|
||||
ignore_errors: True
|
||||
# async: 10
|
||||
# poll: 2
|
||||
register: internet_access_test
|
||||
|
||||
- name: Set has_internet_connection true if wget succeeded
|
||||
set_fact:
|
||||
has_internet_connection: True
|
||||
when: not internet_access_test|failed
|
||||
|
||||
- name: Cleanup internet test file
|
||||
file: path=/tmp/heart-beat.txt
|
||||
state=absent
|
||||
|
||||
- name: Turn off downloads if no internet connection
|
||||
set_fact:
|
||||
no_network: True
|
||||
when: not has_internet_connection
|
||||
|
||||
- name: Testing for xsce_preload
|
||||
set_fact:
|
||||
use_cache: True
|
||||
no_network: True
|
||||
when: xsce_preload == "True"
|
||||
|
||||
- name: Setting wan if detected
|
||||
set_fact:
|
||||
xsce_wan_iface: "{{ discovered_wan_iface }}"
|
||||
device_gw: "{{ discovered_wan_iface }}"
|
||||
when: discovered_wan_iface != "none"
|
||||
|
||||
# returns list of paths
|
||||
- name: Find gateway config based on device
|
||||
shell: "egrep -rn {{ device_gw }} /etc/sysconfig/network-scripts/ifcfg* | gawk -F ':' '{print $1}'"
|
||||
register: ifcfg_gw_device
|
||||
ignore_errors: True
|
||||
changed_when: False
|
||||
when: device_gw != "none"
|
||||
|
||||
# last match wins
|
||||
- name: Setting has ifcfg gw based on device if found
|
||||
set_fact:
|
||||
has_ifcfg_gw: "{{ item|trim }}"
|
||||
ignore_errors: True
|
||||
when: ifcfg_gw_device.stdout_lines is defined and item|trim != "" and item|trim != "/etc/sysconfig/network-scripts/ifcfg-LAN"
|
||||
with_items:
|
||||
- "{{ ifcfg_gw_device.stdout_lines }}"
|
||||
|
||||
# returns path
|
||||
- name: Find active gateway config based on macaddress
|
||||
shell: "egrep -irn {{ ansible_default_ipv4.macaddress }} /etc/sysconfig/network-scripts/ifcfg* | gawk -F ':' '{print $1}' | head -n 1"
|
||||
register: ifcfg_gw_mac
|
||||
ignore_errors: True
|
||||
changed_when: False
|
||||
when: 'ansible_default_ipv4.gateway is defined'
|
||||
|
||||
- name: Set has ifcfg gw based on on macaddress if found
|
||||
set_fact:
|
||||
has_ifcfg_gw: "{{ ifcfg_gw_mac.stdout|trim }}"
|
||||
when: ifcfg_gw_mac is defined and ifcfg_gw_mac.stdout != ""
|
||||
|
||||
# could use something else
|
||||
- name: Find wifi gateway config if present
|
||||
shell: egrep -rn ESSID /etc/sysconfig/network-scripts/ifcfg* | gawk -F ':' '{print $1}' | gawk -F '/' '{print $5}'
|
||||
register: ifcfg_WAN_wifi
|
||||
ignore_errors: True
|
||||
|
||||
#returns file name
|
||||
- name: Setting has_wifi_gw based on ESSID if found
|
||||
set_fact:
|
||||
has_wifi_gw: "{{ item|trim }}"
|
||||
when: ifcfg_WAN_wifi.changed and item|trim != ""
|
||||
with_items:
|
||||
- "{{ ifcfg_WAN_wifi.stdout_lines }}"
|
||||
|
||||
- name: Finding device for wifi AP gateway
|
||||
shell: egrep -rn DEVICE /etc/sysconfig/network-scripts/{{ has_wifi_gw }} | gawk -F '=' '{print $2}'
|
||||
register: AP_device
|
||||
when: has_wifi_gw != "none" and has_ifcfg_gw != "none"
|
||||
|
||||
- name: Setting wifi device
|
||||
set_fact:
|
||||
ap_device: "{{ AP_device.stdout }}"
|
||||
when: AP_device.stdout is defined and AP_device.stdout != ""
|
||||
|
||||
# WIRELESS -- if any wireless is detected as gateway, it becomes WAN
|
||||
- name: Look for any wireless interfaces
|
||||
shell: "cat /proc/net/wireless | grep -v -e Inter -e face | gawk -F: '{print $1}' "
|
||||
register: wireless_list1
|
||||
ignore_errors: True
|
||||
changed_when: False
|
||||
|
||||
- name: Set the discovered wireless, if found
|
||||
set_fact:
|
||||
wifi1: "{{ item|trim }}"
|
||||
discovered_wireless_iface: "{{ item|trim }}"
|
||||
when: item|trim != "" and item|trim != discovered_wan_iface
|
||||
with_items:
|
||||
- "{{ wireless_list1.stdout_lines }}"
|
||||
|
||||
# WIRELESS -- Sigh... Not all drivers update /proc/net/wireless correctly
|
||||
- name: Look for any wireless interfaces take 2
|
||||
shell: "ls -la /sys/class/net/*/phy80211 | awk -F / '{print $5}'"
|
||||
register: wireless_list2
|
||||
ignore_errors: True
|
||||
changed_when: False
|
||||
|
||||
# Last device is used
|
||||
- name: Set the discovered wireless, if found take 2
|
||||
set_fact:
|
||||
wifi2: "{{ item|trim }}"
|
||||
discovered_wireless_iface: "{{ item|trim }}"
|
||||
when: wireless_list2.stdout != "" and item|trim != discovered_wan_iface
|
||||
with_items:
|
||||
- "{{ wireless_list2.stdout_lines }}"
|
||||
|
||||
- name: Count Wifi ifaces
|
||||
shell: "ls -la /sys/class/net/*/phy80211 | awk -F / '{print $5}' | wc -l"
|
||||
register: count_wifi_interfaces
|
||||
|
||||
- name: Remember number of Wifi devices
|
||||
set_fact:
|
||||
num_wifi_interfaces: "{{ count_wifi_interfaces.stdout|int }}"
|
||||
|
||||
# XO hack here ap_device would not be active therefore not set with
|
||||
# wired as gw use ap_device to exclude eth0 from network calulations
|
||||
|
||||
- name: XO override 2 wifi on LAN
|
||||
set_fact:
|
||||
ap_device: "eth0"
|
||||
when: xsce_wan_iface != "eth0" and discovered_wireless_iface != "none" and xo_model == "XO-1.5"
|
||||
|
||||
# takes adapter name
|
||||
- name: Blacklisted wifi adapter
|
||||
set_fact:
|
||||
ap_device: "{{ blacklist_wifi }}"
|
||||
when: blacklist_wifi is defined and discovered_wireless_iface != xsce_wan_iface and num_wifi_interfaces >= "2"
|
||||
|
||||
# LAN - pick non WAN's
|
||||
- name: Create list of LAN (non wan) ifaces
|
||||
shell: ls /sys/class/net | grep -v -e wwlan -e ppp -e lo -e br0 -e tun -e {{ device_gw }} -e {{ ap_device }}
|
||||
register: lan_list_result
|
||||
ignore_errors: True
|
||||
changed_when: false
|
||||
|
||||
# Select an adapter that is not WAN and not wireless
|
||||
# if there is more than one the last one wins
|
||||
- name: Set xsce discovered lan fact
|
||||
set_fact:
|
||||
discovered_lan_iface: "{{ item|trim }}"
|
||||
when: item|trim != discovered_wireless_iface and item|trim != discovered_wan_iface
|
||||
with_items:
|
||||
- "{{ lan_list_result.stdout_lines }}"
|
||||
|
||||
- name: Count LAN ifaces
|
||||
shell: ls /sys/class/net | grep -v -e wwlan -e ppp -e lo -e br0 -e tun -e {{ device_gw }} -e {{ ap_device }} | wc -l
|
||||
register: num_lan_interfaces_result
|
||||
ignore_errors: True
|
||||
changed_when: false
|
||||
|
||||
# facts are apparently all stored as text, so do text comparisons from here on
|
||||
- name: Calulate number of LAN interfaces including WiFi
|
||||
set_fact:
|
||||
num_lan_interfaces: "{{ num_lan_interfaces_result.stdout|int }}"
|
||||
|
||||
# If 2 interfaces found in gateway mode, with one wifi, declare other to be wan
|
||||
#- name: In gateway mode with one wifi adapter, the other is WAN
|
||||
# set_fact:
|
||||
# xsce_wan_iface: "{{ discovered_lan_iface }}"
|
||||
# xsce_lan_iface: "{{ discovered_wireless_iface }}"
|
||||
# num_lan_interfaces: "1"
|
||||
# when: xsce_lan_enabled and xsce_wan_enabled and num_lan_interfaces == "2" and discovered_wireless_iface != "none" and xsce_wan_iface == "none"
|
||||
|
||||
- name: Set the variable for wireless_iface if present
|
||||
set_fact:
|
||||
xsce_wireless_lan_iface: "{{ discovered_wireless_iface }}"
|
||||
when: discovered_wireless_iface != "none" and discovered_wireless_iface != xsce_wan_iface
|
||||
|
||||
#unused
|
||||
- name: Get a list of ifcfg files to delete
|
||||
shell: "ls -1 /etc/sysconfig/network-scripts/ifcfg-* | grep -v -e ifcfg-lo -e ifcfg-WAN -e {{ has_wifi_gw }}"
|
||||
register: ifcfg_files
|
||||
changed_when: False
|
||||
ignore_errors: True
|
||||
when: num_lan_interfaces >= "1" or xsce_wireless_lan_iface != "none"
|
||||
#
|
||||
|
||||
# use value only if present
|
||||
- name: Setting detected lan
|
||||
set_fact:
|
||||
xsce_lan_iface: "{{ discovered_lan_iface }}"
|
||||
when: 'discovered_lan_iface != "none" and num_lan_interfaces == "1"'
|
||||
|
||||
- name: for debian, always use bridging
|
||||
set_fact:
|
||||
xsce_lan_iface: br0
|
||||
when: 'discovered_lan_iface != "none" and num_lan_interfaces >= "1" and is_debian'
|
||||
|
||||
- name: 2 or more devices on the LAN - use bridging
|
||||
set_fact:
|
||||
xsce_lan_iface: br0
|
||||
when: 'discovered_lan_iface != "none" and num_lan_interfaces >= "2" and not is_debian'
|
||||
|
||||
- name: WiFi is on the LAN - use bridging
|
||||
set_fact:
|
||||
xsce_lan_iface: br0
|
||||
when: xsce_wireless_lan_iface != "none"
|
||||
|
||||
# OK try old gw this is a best guess based on what's in
|
||||
# /etc/sysconfig/xs_wan_device's last state intended to
|
||||
# provide a seed value to display in the GUI when no
|
||||
# gateway is present but we had one.
|
||||
- name: Has old gateway and no discovered gateway setting WAN
|
||||
set_fact:
|
||||
gui_wan_iface: "{{ device_gw }}"
|
||||
when: user_wan_iface == "auto" and device_gw != "none" and discovered_wan_iface == "none"
|
||||
|
||||
- name: Add location section to config file
|
||||
ini_file: dest='{{ xsce_config_file }}'
|
||||
section=network
|
||||
option='{{ item.option }}'
|
||||
value='{{ item.value }}'
|
||||
with_items:
|
||||
- option: 'gateway_active'
|
||||
value: '{{ gw_active }}'
|
||||
- option: 'internet_accessible'
|
||||
value: '{{ has_internet_connection }}'
|
||||
- option: 'gateway_ifcfg'
|
||||
value: '{{ has_ifcfg_gw }}'
|
||||
- option: 'detected_gateway'
|
||||
value: '{{ discovered_wan_iface }}'
|
||||
- option: 'prior_gateway'
|
||||
value: '{{ device_gw2 }}'
|
||||
- option: 'wireless_list_1'
|
||||
value: '{{ wifi1 }}'
|
||||
- option: 'wireless_list_2'
|
||||
value: '{{ wifi2 }}'
|
||||
- option: 'num_wifi_interfaces'
|
||||
value: '{{ num_wifi_interfaces }}'
|
||||
- option: 'discovered_wireless_iface'
|
||||
value: '{{ discovered_wireless_iface }}'
|
||||
- option: 'xsce_wireless_lan_iface'
|
||||
value: '{{ xsce_wireless_lan_iface }}'
|
||||
- option: 'num_lan_interfaces'
|
||||
value: '{{ num_lan_interfaces }}'
|
||||
- option: 'detected_lan'
|
||||
value: '{{ discovered_lan_iface }}'
|
||||
- option: 'static_wan'
|
||||
value: '{{ gui_static_wan }}'
|
102
roles/1-prep/tasks/main.yml
Normal file
102
roles/1-prep/tasks/main.yml
Normal file
|
@ -0,0 +1,102 @@
|
|||
- name: Set flag for fedora 18
|
||||
set_fact:
|
||||
is_F18: True
|
||||
when: ansible_distribution_release == "based on Fedora 18" or ansible_distribution_version == "18"
|
||||
|
||||
- name: get the uuidgen program
|
||||
package: name=uuid-runtime
|
||||
state=present
|
||||
when: is_debian
|
||||
|
||||
# for rpi, without rtc, we need time as soon as possible
|
||||
- name: Install chrony package
|
||||
package: name={{ item }}
|
||||
state=present
|
||||
with_items:
|
||||
- chrony
|
||||
tags:
|
||||
- download
|
||||
|
||||
#TODO: Use regexp filter instead of hard-code ip
|
||||
- name: Update chrony config file
|
||||
template: backup=no
|
||||
dest=/etc/chrony.conf
|
||||
src=chrony.conf.j2
|
||||
|
||||
- name: Disable selinux on next boot
|
||||
selinux: state=disabled
|
||||
register: selinux_disabled
|
||||
when: ansible_selinux is defined and ansible_version >= '2' and ansible_selinux or ansible_selinux['status'] is defined and ansible_version < '2' and ansible_selinux['status'] != 'disabled'
|
||||
|
||||
- name: Disable selinux for this session (if needed)
|
||||
command: setenforce Permissive
|
||||
when: selinux_disabled is defined and selinux_disabled.changed
|
||||
|
||||
## DISCOVER PLATFORMS ######
|
||||
- name: Discover if this is a rpi -- if so it has a bcm2709 processor
|
||||
set_fact:
|
||||
rpi_model: "rpi"
|
||||
is_rpi: "True"
|
||||
when: ansible_cmdline["bcm2709.serial"] is defined
|
||||
ignore_errors: true
|
||||
|
||||
- include: prep.yml
|
||||
|
||||
# we need to inialize the ini file
|
||||
- include: xsce_ini.yml
|
||||
|
||||
- include: computed_vars.yml
|
||||
|
||||
- include: detected_network.yml
|
||||
when: not installing
|
||||
|
||||
# Patch Fedora 21+ so usbmount works
|
||||
# Set flag to True that was initialized to False in role defaults
|
||||
# We can't undo this
|
||||
- name: Does udev need patching
|
||||
set_fact:
|
||||
udev_needs_patch: True
|
||||
when: ansible_distribution == "Fedora" and ansible_distribution_version >= "21"
|
||||
|
||||
# Same patch for CentOS 7.2
|
||||
- name: Does udev need patching for Centos
|
||||
set_fact:
|
||||
udev_needs_patch: True
|
||||
when: ansible_distribution == "CentOS" and ansible_distribution_version >= "7.2.1511"
|
||||
|
||||
- name: Copy udevd service to /etc/systemd/system to modify
|
||||
copy: src=/usr/lib/systemd/system/systemd-udevd.service
|
||||
dest=/etc/systemd/system/systemd-udevd.service
|
||||
owner=root
|
||||
group=root
|
||||
mode=0644
|
||||
when: udev_needs_patch
|
||||
|
||||
- name: Change MountFlags from slave to shared
|
||||
lineinfile: backup=no
|
||||
dest=/etc/systemd/system/systemd-udevd.service
|
||||
regexp='^MountFlags'
|
||||
line='MountFlags=shared'
|
||||
state=present
|
||||
when: udev_needs_patch
|
||||
|
||||
- name: Restart systemd-udevd.service
|
||||
service: name=systemd-udevd
|
||||
state=restarted
|
||||
when: udev_needs_patch and not installing
|
||||
|
||||
|
||||
# Put conditional actions for hardware platforms here
|
||||
- include: raspberry_pi_2.yml
|
||||
when: rpi_model != "none"
|
||||
|
||||
- name: Check if the identifier for intel's NUC6 builtin wifi is present
|
||||
shell: "lsusb | grep 8087:0a2b | wc |gawk '{print $1}'"
|
||||
register: usb_NUC6
|
||||
ignore_errors: true
|
||||
|
||||
- name: download the firmware for built in wifi on NUC6
|
||||
get_url: dest=/lib/firmware
|
||||
url={{ xsce_download_url }}/iwlwifi-8000C-13.ucode
|
||||
when: usb_NUC6.stdout|int > 0
|
||||
|
74
roles/1-prep/tasks/prep.yml
Normal file
74
roles/1-prep/tasks/prep.yml
Normal file
|
@ -0,0 +1,74 @@
|
|||
- name: Since f22, dnf has replaced yum, but ansible works with yum
|
||||
command: dnf install -y yum
|
||||
when: ansible_distribution == "Fedora" and ansible_distribution_version|int >= 22
|
||||
|
||||
- name: Install xsce-extra repos
|
||||
template: backup=yes
|
||||
dest=/etc/yum.repos.d/xsce-extra.repo
|
||||
src=xsce-extra.repo
|
||||
owner=root
|
||||
mode=0666
|
||||
when: ansible_distribution != "Debian"
|
||||
|
||||
- name: Install xsce-testing repos
|
||||
template: backup=yes
|
||||
dest=/etc/yum.repos.d/xsce-testing.repo
|
||||
src=xsce-testing.repo
|
||||
owner=root
|
||||
mode=0666
|
||||
when: ansible_distribution != "Debian"
|
||||
|
||||
- name: Install rpmfusion-free-updates repo -- for exfat
|
||||
template: dest=/etc/yum.repos.d/rpmfusion-free-updates.repo
|
||||
src=rpmfusion-free-updates.repo
|
||||
owner=root
|
||||
mode=0666
|
||||
when: ansible_distribution == "Fedora"
|
||||
|
||||
- name: Create /etc/xsce
|
||||
file: path=/etc/xsce
|
||||
owner=root
|
||||
group=root
|
||||
mode=0755
|
||||
state=directory
|
||||
|
||||
# this script can be sourced to get xsce location
|
||||
- name: Create xsce.env file
|
||||
template: src=xsce.env.j2
|
||||
dest=/etc/xsce/xsce.env
|
||||
owner=root
|
||||
group=root
|
||||
mode=0644
|
||||
|
||||
- name: create ansible.d facts directory
|
||||
file: path=/etc/ansible/facts.d
|
||||
owner=root
|
||||
group=root
|
||||
mode=0750
|
||||
state=directory
|
||||
|
||||
- name: local facts script
|
||||
template: src=local_facts.fact.j2
|
||||
dest=/etc/ansible/facts.d/local_facts.fact
|
||||
owner=root
|
||||
group=root
|
||||
mode=0700
|
||||
|
||||
- name: re-read facts
|
||||
setup: filter=ansible_local
|
||||
|
||||
- name: Set XO model and preload
|
||||
set_fact:
|
||||
phplib_dir: '{{ ansible_local["local_facts"]["phplib_dir"] }}'
|
||||
xo_model: '{{ ansible_local["local_facts"]["xo_model"] }}'
|
||||
xsce_preload: '{{ ansible_local["local_facts"]["xsce_preload"] }}'
|
||||
|
||||
- name: Install script to fully initialize network config, and/or collect data
|
||||
# calling xs-network-reset w/ snapshot name, stores info, but aborts reset
|
||||
# intended as a convenience function for us
|
||||
template: src=xs-network-reset
|
||||
dest=/usr/bin
|
||||
owner=root
|
||||
group=root
|
||||
mode=0755
|
||||
|
62
roles/1-prep/tasks/raspberry_pi_2.yml
Normal file
62
roles/1-prep/tasks/raspberry_pi_2.yml
Normal file
|
@ -0,0 +1,62 @@
|
|||
# Setup specific to the Raspberry Pi
|
||||
#
|
||||
- name: Add a udev rule to transfer hwclock to system clock at dev creation
|
||||
template: src=92-rtc-i2c.rules
|
||||
dest=/etc/udev/rules.d/92-rtc-i2c.rules
|
||||
owner=root
|
||||
group=root
|
||||
mode=0644
|
||||
when: rtc_id is defined and rtc_id != "none"
|
||||
|
||||
#
|
||||
# RTC requires a change to the device tree (and reboot)
|
||||
- name: Check for needing to enable i2c rtc device in config.txt
|
||||
lineinfile: dest=/boot/config.txt
|
||||
line="dtoverlay=i2c-rtc,{{ rtc_id }}=on"
|
||||
state=present
|
||||
register: rpiconfig
|
||||
when: rtc_id != "none"
|
||||
|
||||
|
||||
- name: Add a udev rule to transfer hwclock to system clock at dev creation
|
||||
template: src=92-rtc-i2c.rules
|
||||
dest=/etc/udev/rules.d/92-rtc-i2c.rules
|
||||
owner=root
|
||||
group=root
|
||||
mode=0644
|
||||
when: rtc_id != "none"
|
||||
|
||||
- name: pre-Install packages
|
||||
package: name={{ item }}
|
||||
state=latest
|
||||
with_items:
|
||||
- ntp
|
||||
|
||||
- name: increase the swap file size (kalite pip download fails)
|
||||
lineinfile: regexp="^CONF_SWAPSIZE"
|
||||
line=CONF_SWAPSIZE=500
|
||||
dest=/etc/dphys-swapfile
|
||||
when: is_debian
|
||||
|
||||
- name: restart the swqp service
|
||||
command: /etc/init.d/dphys-swapfile restart
|
||||
when: is_debian
|
||||
|
||||
- name: Add rpi rootfs resizing service
|
||||
template: src={{ item.src }}
|
||||
dest={{ item.dest }}
|
||||
owner=root
|
||||
group=root
|
||||
mode={{ item.mode }}
|
||||
with_items:
|
||||
- { src: 'xsce-rpi-max-rootfs.sh', dest: '/usr/sbin/xsce-rpi-max-rootfs.sh', mode: '0755'}
|
||||
- { src: 'xsce-rpi-root-resize.service', dest: '/etc/systemd/system/xsce-rpi-root-resize.service', mode: '0644'}
|
||||
|
||||
- name: Enable rootfs resizing service
|
||||
service: name=xsce-rpi-root-resize
|
||||
enabled=yes
|
||||
- name: Reboot if the config.txt was changed
|
||||
command: /sbin/reboot
|
||||
when: rpiconfig.changed
|
||||
async: 300
|
||||
poll: 120
|
34
roles/1-prep/tasks/xsce_ini.yml
Executable file
34
roles/1-prep/tasks/xsce_ini.yml
Executable file
|
@ -0,0 +1,34 @@
|
|||
# workaround for fact that auto create does not work on ini_file
|
||||
- name: Create xsce config file
|
||||
file: dest='{{ xsce_config_file }}'
|
||||
state=touch
|
||||
|
||||
- name: Add location section to config file
|
||||
ini_file: dest='{{ xsce_config_file }}'
|
||||
section=location
|
||||
option='{{ item.option }}'
|
||||
value='{{ item.value }}'
|
||||
with_items:
|
||||
- option: 'xsce_base'
|
||||
value: '{{ xsce_base }}'
|
||||
- option: 'xsce_dir'
|
||||
value: '{{ xsce_dir }}'
|
||||
|
||||
- name: add version section
|
||||
ini_file: dest='{{ xsce_config_file }}'
|
||||
section=version
|
||||
option='{{ item.option }}'
|
||||
value='{{ item.value }}'
|
||||
with_items:
|
||||
- option: 'distribution'
|
||||
value: '{{ ansible_distribution }}'
|
||||
- option: 'arch'
|
||||
value: '{{ ansible_architecture }}'
|
||||
- option: 'xsce_branch'
|
||||
value: '{{ ansible_local["local_facts"]["xsce_branch"] }}'
|
||||
- option: 'xsce_commit'
|
||||
value: '{{ ansible_local["local_facts"]["xsce_commit"] }}'
|
||||
- option: 'install_date'
|
||||
value: '{{ ansible_date_time["iso8601"] }}'
|
||||
- option: 'install_xo'
|
||||
value: '{{ xo_model }}'
|
3
roles/1-prep/templates/92-rtc-i2c.rules
Normal file
3
roles/1-prep/templates/92-rtc-i2c.rules
Normal file
|
@ -0,0 +1,3 @@
|
|||
# /etc/udev/rules.d/92-rtc-i2c.rules
|
||||
#
|
||||
ACTION=="add", SUBSYSTEM=="rtc", ATTRS{hctosys}=="0", RUN+="/usr/sbin/hwclock -s --utc"
|
46
roles/1-prep/templates/chrony.conf.j2
Normal file
46
roles/1-prep/templates/chrony.conf.j2
Normal file
|
@ -0,0 +1,46 @@
|
|||
# Use public servers from the pool.ntp.org project.
|
||||
# Please consider joining the pool (http://www.pool.ntp.org/join.html).
|
||||
server 0.fedora.pool.ntp.org iburst
|
||||
server 1.fedora.pool.ntp.org iburst
|
||||
server 2.fedora.pool.ntp.org iburst
|
||||
server 3.fedora.pool.ntp.org iburst
|
||||
|
||||
# Ignore stratum in source selection.
|
||||
stratumweight 0
|
||||
|
||||
# Record the rate at which the system clock gains/losses time.
|
||||
driftfile /var/lib/chrony/drift
|
||||
|
||||
# Enable kernel RTC synchronization.
|
||||
rtcsync
|
||||
|
||||
# In first three updates step the system clock instead of slew
|
||||
# if the adjustment is larger than 10 seconds.
|
||||
makestep 10 3
|
||||
|
||||
# Allow NTP client access from local network.
|
||||
allow 172.18
|
||||
|
||||
# Listen for commands only on localhost.
|
||||
bindcmdaddress 127.0.0.1
|
||||
bindcmdaddress ::1
|
||||
|
||||
# Serve time even if not synchronized to any NTP server.
|
||||
local stratum 10
|
||||
|
||||
keyfile /etc/chrony.keys
|
||||
|
||||
# Specify the key used as password for chronyc.
|
||||
commandkey 1
|
||||
|
||||
# Generate command key if missing.
|
||||
generatecommandkey
|
||||
|
||||
# Disable logging of client accesses.
|
||||
noclientlog
|
||||
|
||||
# Send a message to syslog if a clock adjustment is larger than 0.5 seconds.
|
||||
logchange 0.5
|
||||
|
||||
#log measurements statistics tracking
|
||||
logdir /var/log/chrony
|
65
roles/1-prep/templates/local_facts.fact.j2
Normal file
65
roles/1-prep/templates/local_facts.fact.j2
Normal file
|
@ -0,0 +1,65 @@
|
|||
#!/bin/bash
|
||||
OS=`grep ^ID= /etc/*release|cut -d= -f2`
|
||||
OS=${OS//\"/}
|
||||
|
||||
# enable this install config to be tracked
|
||||
if [ ! -f /etc/xsce/uuid ]; then
|
||||
uuidgen > /etc/xsce/uuid
|
||||
fi
|
||||
UUID=`cat /etc/xsce/uuid`
|
||||
|
||||
source /etc/xsce/xsce.env
|
||||
cd $XSCE_DIR
|
||||
|
||||
# get current version
|
||||
BRANCH=`git rev-parse --abbrev-ref HEAD`
|
||||
COMMIT=`git rev-parse --verify HEAD`
|
||||
|
||||
if [ -d /usr/lib64/php ]
|
||||
then
|
||||
PHPLIB_DIR=/usr/lib64/php
|
||||
else
|
||||
if [ -d /usr/lib/php5 ]; then
|
||||
PHPLIB_DIR=/usr/lib/php5
|
||||
else
|
||||
PHPLIB_DIR=/usr/lib/php
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -f /proc/device-tree/mfg-data/MN ]
|
||||
then
|
||||
XO_VERSION=`cat /proc/device-tree/mfg-data/MN`
|
||||
else
|
||||
XO_VERSION="none"
|
||||
fi
|
||||
|
||||
if [ -f /etc/xsce/xsce.env ]
|
||||
then
|
||||
. /etc/xsce/xsce.env
|
||||
if [ -z $BASE_VERSION ]
|
||||
then
|
||||
BASE_VERSION="0"
|
||||
fi
|
||||
BASE="$BASE_VERSION"
|
||||
else
|
||||
BASE="0"
|
||||
fi
|
||||
|
||||
if [ -f /.preload ]
|
||||
then
|
||||
PRELOAD="True"
|
||||
else
|
||||
PRELOAD="False"
|
||||
fi
|
||||
ANSIBLE_VERSION=$(ansible --version|head -n 1|cut -f 2 -d " ")
|
||||
cat <<EOF
|
||||
{"phplib_dir" : "$PHPLIB_DIR",
|
||||
"xsce_branch" : "$BRANCH",
|
||||
"xsce_commit" : "$COMMIT",
|
||||
"xsce_uuid" : "$UUID",
|
||||
"xo_model" : "$XO_VERSION",
|
||||
"xsce_base_ver" : "$BASE",
|
||||
"ansble_version" : "$ANSIBLE_VERSION",
|
||||
"os" : "$OS",
|
||||
"xsce_preload" : "$PRELOAD"}
|
||||
EOF
|
24
roles/1-prep/templates/rpmfusion-free-updates.repo
Normal file
24
roles/1-prep/templates/rpmfusion-free-updates.repo
Normal file
|
@ -0,0 +1,24 @@
|
|||
[xsce-rpmfusion-free-updates]
|
||||
name=xsce-RPM Fusion for Fedora $releasever - Free - Updates
|
||||
#baseurl=http://download1.rpmfusion.org/free/fedora/updates/$releasever/$basearch/
|
||||
mirrorlist=http://mirrors.rpmfusion.org/mirrorlist?repo=free-fedora-updates-released-$releasever&arch=$basearch
|
||||
enabled=0
|
||||
gpgcheck=0
|
||||
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-rpmfusion-free-fedora-$releasever
|
||||
|
||||
[xsce-rpmfusion-free-updates-debuginfo]
|
||||
name=xsce-RPM Fusion for Fedora $releasever - Free - Updates Debug
|
||||
#baseurl=http://download1.rpmfusion.org/free/fedora/updates/$releasever/$basearch/debug/
|
||||
mirrorlist=http://mirrors.rpmfusion.org/mirrorlist?repo=free-fedora-updates-released-debug-$releasever&arch=$basearch
|
||||
enabled=0
|
||||
gpgcheck=1
|
||||
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-rpmfusion-free-fedora-$releasever
|
||||
|
||||
[xsce-rpmfusion-free-updates-source]
|
||||
name=xsce-RPM Fusion for Fedora $releasever - Free - Updates Source
|
||||
#baseurl=http://download1.rpmfusion.org/free/fedora/updates/$releasever/SRPMS/
|
||||
mirrorlist=http://mirrors.rpmfusion.org/mirrorlist?repo=free-fedora-updates-released-source-$releasever&arch=$basearch
|
||||
enabled=0
|
||||
gpgcheck=1
|
||||
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-rpmfusion-free-fedora-$releasever
|
||||
|
137
roles/1-prep/templates/xs-network-reset
Executable file
137
roles/1-prep/templates/xs-network-reset
Executable file
|
@ -0,0 +1,137 @@
|
|||
#!/bin/bash
|
||||
# if called w/ parameter, skip the reset, create diagnostic package w/ param as file name
|
||||
SCRIPTDIR=$(cd `dirname $0` pwd)
|
||||
diagnose_name=
|
||||
if [ $# -ne 0 ]; then
|
||||
basket=$1
|
||||
diagnose_name=$1
|
||||
else
|
||||
basket=netlog.$$
|
||||
fi
|
||||
|
||||
# collect all the network info in one place
|
||||
mkdir -p /tmp/$basket
|
||||
cat << EOF > /tmp/script2overview
|
||||
#!/bin/bash
|
||||
# generate the body overview part diagnostic package about network
|
||||
echo "=========================================================="
|
||||
for f in \$(ls /etc/sysconfig/network-scripts/ifcfg-*|gawk '{printf(" %s",\$1)}'); do
|
||||
echo
|
||||
echo \$f
|
||||
cat \$f
|
||||
done
|
||||
echo
|
||||
echo "=========================================================="
|
||||
echo ifconfig
|
||||
ifconfig
|
||||
echo
|
||||
echo "=========================================================="
|
||||
echo ip addr
|
||||
ip addr
|
||||
echo
|
||||
echo "=========================================================="
|
||||
echo "brctl show"
|
||||
brctl show
|
||||
echo
|
||||
echo "=========================================================="
|
||||
echo "/etc/resolv.conf"
|
||||
cat /etc/resolv.conf
|
||||
echo
|
||||
echo "=========================================================="
|
||||
echo "cat /etc/xsce/xsce.ini"
|
||||
cat /etc/xsce/xsce.ini
|
||||
echo
|
||||
echo "=========================================================="
|
||||
echo "routing table"
|
||||
netstat -rn
|
||||
echo
|
||||
echo "=========================================================="
|
||||
echo "install log -- last 50 lines"
|
||||
tail -50 /opt/schoolserver/xsce/xsce-install.log
|
||||
echo
|
||||
echo "=========================================================="
|
||||
echo "xsce-network log -- last 50 lines"
|
||||
if [ -f /opt/schoolserver/xsce/xsce-network.log ]; then
|
||||
tail -50 /opt/schoolserver/xsce/xsce-network.log
|
||||
else
|
||||
echo no xsce-network.log
|
||||
fi
|
||||
echo
|
||||
echo "=========================================================="
|
||||
cat /etc/fedora-release | grep 18
|
||||
if [ \$? -eq 0 ]; then
|
||||
echo "nmcli conn list"
|
||||
nmcli conn list 3>&2
|
||||
else
|
||||
echo "nmcli conn show"
|
||||
nmcli conn show 3>&2
|
||||
fi
|
||||
echo
|
||||
echo "=========================================================="
|
||||
echo nmcli dev wifi list
|
||||
nmcli dev wifi list
|
||||
EOF
|
||||
chmod 755 /tmp/script2overview
|
||||
/tmp/script2overview > /tmp/$basket/overview
|
||||
|
||||
if [ -f /opt/schoolserver/xsce/xsce-network.log ]; then
|
||||
cp /opt/schoolserver/xsce/xsce-network.log /tmp/$basket
|
||||
else
|
||||
touch /tmp/$basket/no_xsce-network.log
|
||||
fi
|
||||
|
||||
if [ -f /etc/sysconfig/xs_domain_name ];then
|
||||
cp -p /etc/sysconfig/xs_domain_name /tmp/$basket
|
||||
else
|
||||
touch /tmp/$basket/xs_domain_name_not_set
|
||||
fi
|
||||
|
||||
if [ -f /etc/sysconfig/xs_lan_device ];then
|
||||
cp -p /etc/sysconfig/xs_lan_device /tmp/$basket
|
||||
else
|
||||
touch /tmp/$basket/xs_lan_device_not_set
|
||||
fi
|
||||
if [ -f /etc/sysconfig/xs_wan_device ];then
|
||||
cp -p /etc/sysconfig/xs_wan_device /tmp/$basket
|
||||
else
|
||||
touch /tmp/$basket/xs_wan_device_not_set
|
||||
fi
|
||||
ls /etc/NetworkManager/system-connections > /dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
cp -rp /etc/NetworkManager/system-connections /tmp/$basket
|
||||
fi
|
||||
cp /etc/sysconfig/network-scripts/ifcfg-* /tmp/$basket
|
||||
if [ -f /opt/schoolserver/xsce/xsce-network.log ]; then
|
||||
cp -p /opt/schoolserver/xsce/xsce-network.log /tmp/$basket
|
||||
fi
|
||||
|
||||
mkdir -p /etc/xsce/diagnose/
|
||||
if [ ! -z $diagnose_name ];then
|
||||
pushd /tmp > /dev/null
|
||||
tar czf /etc/xsce/diagnose/$basket.tgz $basket/*
|
||||
popd > /dev/null
|
||||
rm -rf /tmp/$basket
|
||||
exit 0
|
||||
else
|
||||
pushd /tmp > /dev/null
|
||||
tar czf /etc/xsce/diagnose/$basket.tgz $basket/*
|
||||
popd > /dev/null
|
||||
rm -rf /tmp/$basket
|
||||
fi
|
||||
|
||||
# clear out all the memory variables and let auto-configure start from scratch
|
||||
rm -rf /etc/sysconfig/xs_domain_name
|
||||
rm -rf /etc/sysconfig/xs_lan_device
|
||||
rm -rf /etc/sysconfig/xs_wan_device
|
||||
rm -rf /etc/NetworkManager/system-connestions/*
|
||||
if [ -f /etc/sysconfig/network-scripts/ifcfg-WAN ];then
|
||||
mv /etc/sysconfig/network-scripts/ifcfg-WAN /root
|
||||
echo -e "\n\nWAN setup file moved to /root for safekeeping.\n\n"
|
||||
fi
|
||||
|
||||
ls -1 /etc/sysconfig/network-scripts/ifcfg-*|grep -v -e ifcfg-lo
|
||||
if [ $? -eq 0 ]; then
|
||||
ls -1 /etc/sysconfig/network-scripts/ifcfg-*|grep -v -e ifcfg-lo|xargs rm
|
||||
fi
|
||||
|
||||
echo -e "\n\nAll Network variables erased. Now run 'xsce-network' to set up the new network configuration.\n\nPlease see /opt/schoolserver/xsce/docs/GETTING_HELP.rst for ways to get help or \nprovide the feedback which will improve XSCE\n\n"
|
16
roles/1-prep/templates/xsce-extra.repo
Normal file
16
roles/1-prep/templates/xsce-extra.repo
Normal file
|
@ -0,0 +1,16 @@
|
|||
[xsce-extra]
|
||||
name=xsce-extra
|
||||
failovermethod=priority
|
||||
baseurl=http://download.unleashkids.org/xsce/repos/xs-extra/
|
||||
enabled=1
|
||||
metadata_expire=1d
|
||||
gpgcheck=0
|
||||
|
||||
[dummy-config]
|
||||
name=dummy-config
|
||||
failovermethod=priority
|
||||
baseurl=http://download.unleashkids.org/xsce/repos/xsce-extra/
|
||||
enabled=1
|
||||
metadata_expire=1d
|
||||
gpgcheck=0
|
||||
|
20
roles/1-prep/templates/xsce-rpi-max-rootfs.sh
Normal file
20
roles/1-prep/templates/xsce-rpi-max-rootfs.sh
Normal file
|
@ -0,0 +1,20 @@
|
|||
#!/bin/bash -x
|
||||
# Resize rootfs and its partition on the rpi SD card to maximum size
|
||||
# To be used by systemd service on boot
|
||||
# Only resizes if /.resize-rootfs exists
|
||||
# Assumes root is last partition
|
||||
# Only works on F22 + where resizepart command exists
|
||||
# Assumes sd card style partition name like <device>p<partition number>
|
||||
|
||||
if [ -f /.resize-rootfs ];then
|
||||
echo "$0: maximizing rootfs partion"
|
||||
# Calculate root partition
|
||||
root_part=`lsblk -aP -o NAME,MOUNTPOINT|grep 'MOUNTPOINT="/"' |awk -F\" '{ print $2 }'`
|
||||
root_dev=${root_part:0:-2}
|
||||
root_part_no=${root_part: (-1)}
|
||||
|
||||
# Resize partition
|
||||
parted -s /dev/$root_dev resizepart $root_part_no 100%
|
||||
resize2fs /dev/$root_part
|
||||
rm /.resize-rootfs
|
||||
fi
|
12
roles/1-prep/templates/xsce-rpi-root-resize.service
Normal file
12
roles/1-prep/templates/xsce-rpi-root-resize.service
Normal file
|
@ -0,0 +1,12 @@
|
|||
[Unit]
|
||||
Description=Root Filesystem Auto-Resizer
|
||||
|
||||
[Service]
|
||||
Environment=TERM=linux
|
||||
Type=oneshot
|
||||
ExecStart=/usr/sbin/xsce-rpi-max-rootfs.sh
|
||||
StandardError=syslog
|
||||
RemainAfterExit=no
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
7
roles/1-prep/templates/xsce-testing.repo
Normal file
7
roles/1-prep/templates/xsce-testing.repo
Normal file
|
@ -0,0 +1,7 @@
|
|||
[xsce-testing]
|
||||
name=xsce-testing
|
||||
failovermethod=priority
|
||||
baseurl=http://download.unleashkids.org/xsce/repos/xsce/testing
|
||||
enabled=1
|
||||
metadata_expire=1d
|
||||
gpgcheck=0
|
6
roles/1-prep/templates/xsce.env.j2
Normal file
6
roles/1-prep/templates/xsce.env.j2
Normal file
|
@ -0,0 +1,6 @@
|
|||
# This is a configuration file for XSCE
|
||||
# It can sourced in a shell script or read into an application
|
||||
XSCE_BASE_PATH={{ xsce_base }}
|
||||
XSCE_DIR={{ xsce_dir }}
|
||||
OS={{ ansible_distribution }}
|
||||
WWWROOT={{ doc_root }}
|
6
roles/2-common/README.rst
Normal file
6
roles/2-common/README.rst
Normal file
|
@ -0,0 +1,6 @@
|
|||
=============
|
||||
Common README
|
||||
=============
|
||||
|
||||
This role aggregates roles containing packages and a few other tasks that are common to all platforms
|
||||
and are required before creating a functioning server.
|
38
roles/2-common/tasks/centos.yml
Normal file
38
roles/2-common/tasks/centos.yml
Normal file
|
@ -0,0 +1,38 @@
|
|||
- name: Centos Server specific tasks
|
||||
command: echo Starting centos.yml
|
||||
|
||||
- name: Keep yum cache
|
||||
ini_file: dest=/etc/yum.conf
|
||||
section=main
|
||||
option=keepcache
|
||||
value=1
|
||||
|
||||
- name: Install epel-release for CentOS
|
||||
package: name={{ item }}
|
||||
state=present
|
||||
with_items:
|
||||
- epel-release
|
||||
|
||||
- name: Install XECE repo for CentOS
|
||||
template: src={{ item }} dest=/etc/yum.repos.d/ owner=root group=root mode=0644
|
||||
with_items:
|
||||
- xsce-centos.repo
|
||||
- li.nux.ro.repo
|
||||
|
||||
- name: Disable updating ejabberd on CentOS
|
||||
shell: sed -i -e '/^enabled=/a exclude=ejabberd' {{ item }}
|
||||
with_items:
|
||||
- /etc/yum.repos.d/CentOS-Base.repo
|
||||
- /etc/yum.repos.d/CentOS-CR.repo
|
||||
- /etc/yum.repos.d/CentOS-fasttrack.repo
|
||||
- /etc/yum.repos.d/CentOS-Vault.repo
|
||||
|
||||
- name: Disable updating ansible on CentOS
|
||||
shell: sed -i -e '/^enabled=/a exclude=ansible' {{ item }}
|
||||
with_items:
|
||||
- /etc/yum.repos.d/CentOS-Base.repo
|
||||
- /etc/yum.repos.d/CentOS-CR.repo
|
||||
- /etc/yum.repos.d/CentOS-fasttrack.repo
|
||||
- /etc/yum.repos.d/CentOS-Vault.repo
|
||||
when: ansible_distribution == "CentOS"
|
||||
|
30
roles/2-common/tasks/fedora.yml
Normal file
30
roles/2-common/tasks/fedora.yml
Normal file
|
@ -0,0 +1,30 @@
|
|||
- name: Keep yum cache
|
||||
ini_file: dest=/etc/yum.conf
|
||||
section=main
|
||||
option=keepcache
|
||||
value=1
|
||||
|
||||
- name: Install Fedora specifc packages
|
||||
package: name={{ item }}
|
||||
state=present
|
||||
with_items:
|
||||
- mtd-utils
|
||||
|
||||
- name: Install optional exFAT packages for Fedora
|
||||
shell: yum --enablerepo=rpmfusion-free-updates install exfat-utils fuse-exfat
|
||||
when: exFAT_enabled == "True"
|
||||
|
||||
- name: Disable updating ejabberd on Fedora
|
||||
shell: sed -i -e '/^enabled=/a exclude=ejabberd' {{ item }}
|
||||
with_items:
|
||||
- /etc/yum.repos.d/fedora.repo
|
||||
- /etc/yum.repos.d/fedora-updates.repo
|
||||
- /etc/yum.repos.d/fedora-updates-testing.repo
|
||||
|
||||
- name: Disable updating ansible on Fedora
|
||||
shell: sed -i -e '/^enabled=/a exclude=ansible' {{ item }}
|
||||
with_items:
|
||||
- /etc/yum.repos.d/fedora.repo
|
||||
- /etc/yum.repos.d/fedora-updates.repo
|
||||
- /etc/yum.repos.d/fedora-updates-testing.repo
|
||||
when: ansible_distribution == "Fedora"
|
68
roles/2-common/tasks/fl.yml
Normal file
68
roles/2-common/tasks/fl.yml
Normal file
|
@ -0,0 +1,68 @@
|
|||
- name: Create /opt/schoolserver/xsce
|
||||
file: path={{ xsce_dir }}
|
||||
owner=root
|
||||
group=root
|
||||
mode=0755
|
||||
state=directory
|
||||
|
||||
- name: Create /opt/schoolserver/yum-packages
|
||||
file: path={{ yum_packages_dir }}
|
||||
owner=root
|
||||
group=root
|
||||
mode=0755
|
||||
state=directory
|
||||
|
||||
- name: Create /opt/schoolserver/pip-packages
|
||||
file: path={{ pip_packages_dir }}
|
||||
owner=root
|
||||
group=root
|
||||
mode=0755
|
||||
state=directory
|
||||
|
||||
- name: Create /opt/schoolserver/downloads
|
||||
file: path={{ downloads_dir }}
|
||||
owner=root
|
||||
group=root
|
||||
mode=0755
|
||||
state=directory
|
||||
|
||||
- name: Create various library directories
|
||||
file: path={{ item }}
|
||||
owner=root
|
||||
group=root
|
||||
mode=0755
|
||||
state=directory
|
||||
with_items:
|
||||
- /library/downloads/zims
|
||||
- /library/downloads/rachel
|
||||
- /library/working/zims
|
||||
- /library/working/rachel
|
||||
- "{{ xsce_zim_path }}/content"
|
||||
- "{{ xsce_zim_path }}/index"
|
||||
- "{{ rachel_doc_root }}"
|
||||
|
||||
- name: Create directory for common packages
|
||||
file: path={{ item }}
|
||||
mode=0755
|
||||
owner=root
|
||||
group=root
|
||||
state=directory
|
||||
with_items:
|
||||
- "{{ doc_root }}/common/css"
|
||||
- "{{ doc_root }}/common/js"
|
||||
- "{{ doc_root }}/common/fonts"
|
||||
- "{{ doc_root }}/common/html"
|
||||
- "{{ doc_root }}/common/images"
|
||||
- "{{ doc_root }}/common/assets"
|
||||
- "{{ doc_root }}/common/menu-defs"
|
||||
|
||||
- name: Create olpc-scripts directory
|
||||
file: path={{ item }}
|
||||
owner=root
|
||||
group=root
|
||||
mode=0755
|
||||
state=directory
|
||||
with_items:
|
||||
- /etc/sysconfig/olpc-scripts/
|
||||
- /etc/sysconfig/olpc-scripts/setup.d/installed/
|
||||
|
44
roles/2-common/tasks/main.yml
Normal file
44
roles/2-common/tasks/main.yml
Normal file
|
@ -0,0 +1,44 @@
|
|||
|
||||
- include: xsce_ini.yml
|
||||
|
||||
# create the directory structure for XSCE
|
||||
- include: fl.yml
|
||||
|
||||
- include: xo.yml
|
||||
when: xo_model != "none" or osbuilder is defined
|
||||
|
||||
- include: centos.yml
|
||||
when: ansible_distribution == "CentOS"
|
||||
|
||||
- include: fedora.yml
|
||||
when: ansible_distribution == "Fedora"
|
||||
|
||||
# the following installs common packages for both debian and fedora
|
||||
- include: packages.yml
|
||||
|
||||
- sysctl: name=net.ipv4.ip_forward value=1 state=present
|
||||
- sysctl: name=net.ipv4.conf.default.rp_filter value=1 state=present
|
||||
- sysctl: name=net.ipv4.conf.default.accept_source_route value=0 state=present
|
||||
- sysctl: name=kernel.sysrq value=1 state=present
|
||||
- sysctl: name=kernel.core_uses_pid value=1 state=present
|
||||
- sysctl: name=net.ipv4.tcp_syncookies value=1 state=present
|
||||
- sysctl: name=kernel.shmmax value=268435456 state=present
|
||||
# IPv6 disabled
|
||||
- sysctl: name=net.ipv6.conf.all.disable_ipv6 value=1 state=present
|
||||
- sysctl: name=net.ipv6.conf.default.disable_ipv6 value=1 state=present
|
||||
- sysctl: name=net.ipv6.conf.lo.disable_ipv6 value=1 state=present
|
||||
|
||||
- name: Set default Timezone
|
||||
shell: ln -sf /usr/share/zoneinfo/{{ xsce_TZ }} /etc/localtime
|
||||
when: xsce_TZ is defined and xsce_TZ != ""
|
||||
|
||||
- name: Install custom profile file
|
||||
template: dest=/etc/profile.d/zzz_xsce.sh
|
||||
src=zzz_xsce.sh
|
||||
owner=root
|
||||
mode=0644
|
||||
backup=no
|
||||
|
||||
- include: net_mods.yml
|
||||
when: not is_debian and not is_F18
|
||||
|
31
roles/2-common/tasks/net_mods.yml
Normal file
31
roles/2-common/tasks/net_mods.yml
Normal file
|
@ -0,0 +1,31 @@
|
|||
- name: Disable systemd-networkd.service
|
||||
service: name=systemd-networkd.service
|
||||
enabled=no
|
||||
when: not is_centos
|
||||
|
||||
- name: Mask systemd-networkd.service
|
||||
shell: 'systemctl mask systemd-networkd'
|
||||
when: not is_centos
|
||||
|
||||
- name: Disable systemd-hostnamed.service
|
||||
service: name=systemd-hostnamed.service
|
||||
enabled=no
|
||||
|
||||
- name: Disable dbus-org.freedesktop.hostname1.service
|
||||
service: name=dbus-org.freedesktop.hostname1
|
||||
enabled=no
|
||||
|
||||
- name: Mask dbus-org.freedesktop.hostname1.service
|
||||
shell: 'systemctl mask dbus-org.freedesktop.hostname1'
|
||||
|
||||
- name: Disable network.service
|
||||
service: name=network
|
||||
enabled=no
|
||||
|
||||
- name: Mask network.service
|
||||
shell: 'systemctl mask network.service'
|
||||
|
||||
# Network Manager starts this if needed
|
||||
- name: Disable wpa_supplicant
|
||||
service: name=wpa_supplicant
|
||||
enabled=no
|
118
roles/2-common/tasks/packages.yml
Normal file
118
roles/2-common/tasks/packages.yml
Normal file
|
@ -0,0 +1,118 @@
|
|||
- name: install yum deps for arm!!!
|
||||
shell: dnf install -y python-urlgrabber pyxattr yum-metadata-parser
|
||||
when: ansible_distribution == "Fedora" and ansible_machine == "armv7l" and ansible_distribution_version|int >= 22
|
||||
|
||||
- name: install yum from Fedora 23 for arm!!!
|
||||
shell: dnf install -y https://kojipkgs.fedoraproject.org//packages/yum/3.4.3/506.fc23/noarch/yum-3.4.3-506.fc23.noarch.rpm python-dnf
|
||||
when: ansible_distribution == "Fedora" and ansible_machine == "armv7l" and ansible_distribution_version|int >= 22
|
||||
|
||||
- name: install yum if it has been dropped from our distribution -- Fedora 22 uses dnf!!!
|
||||
shell: dnf install -y yum
|
||||
when: ansible_distribution == "Fedora" and ansible_distribution_version|int >= 22 and ansible_machine != "armv7l"
|
||||
|
||||
- name: get the createrepo program
|
||||
package: name=createrepo
|
||||
state=present
|
||||
when: ansible_distribution != "Debian"
|
||||
|
||||
- name: Create local repo
|
||||
shell: createrepo {{ yum_packages_dir }}
|
||||
when: ansible_distribution != "Debian"
|
||||
|
||||
- name: Install local repo file.
|
||||
template: dest=/etc/yum.repos.d/xsce-local.repo
|
||||
src=local.repo
|
||||
owner=root
|
||||
mode=0644
|
||||
when: ansible_distribution != "Debian"
|
||||
|
||||
- name: Install yum packages
|
||||
package: name={{ item }}
|
||||
state=present
|
||||
with_items:
|
||||
- yum-utils
|
||||
- createrepo
|
||||
- wpa_supplicant
|
||||
- linux-firmware
|
||||
- syslog
|
||||
- xml-common
|
||||
when: ansible_distribution != "Debian"
|
||||
tags:
|
||||
- download
|
||||
|
||||
- name: Install yum packages for Debian
|
||||
package: name={{ item }}
|
||||
state=present
|
||||
with_items:
|
||||
- inetutils-syslogd
|
||||
- wpasupplicant
|
||||
when: ansible_distribution == "Debian"
|
||||
tags:
|
||||
- download
|
||||
|
||||
- name: Install common packages
|
||||
package: name={{ item }}
|
||||
state=present
|
||||
with_items:
|
||||
- acpid
|
||||
- mlocate
|
||||
- rsync
|
||||
- htop
|
||||
- etckeeper
|
||||
- python-passlib
|
||||
- usbmount
|
||||
- net-tools
|
||||
- openssh-server
|
||||
- sudo
|
||||
- logrotate
|
||||
- make
|
||||
- tar
|
||||
- unzip
|
||||
- bzip2
|
||||
- i2c-tools
|
||||
- bridge-utils
|
||||
- usbutils
|
||||
- hostapd
|
||||
- wget
|
||||
- openssl #FC 18 does not supply, but pear requires
|
||||
- gawk
|
||||
tags:
|
||||
- download
|
||||
|
||||
- name: Update common packages (not debian
|
||||
package: name={{ item }}
|
||||
state=latest
|
||||
with_items:
|
||||
- NetworkManager
|
||||
- glibc # CVE-2015-7547
|
||||
- bash
|
||||
- iptables
|
||||
when: ansible_distribution != "Debian"
|
||||
tags:
|
||||
- download
|
||||
|
||||
- name: Update common packages (debian)
|
||||
package: name={{ item }}
|
||||
state=latest
|
||||
with_items:
|
||||
- libc6
|
||||
- bash
|
||||
- iptables
|
||||
when: ansible_distribution == "Debian"
|
||||
tags:
|
||||
- download
|
||||
|
||||
|
||||
# instuctions state to start with a fully updated system before starting, stop using
|
||||
# ansible as a crutch for developers not following the directions and taking short-cuts
|
||||
|
||||
#- name: If version of Network manager has changed, subsequent nmcli commands will fail,restart now
|
||||
# service: name=NetworkManager
|
||||
# state=restarted
|
||||
# when: not installing
|
||||
# the above should use a handler - all reboots should wait until all
|
||||
# mods are preformed
|
||||
|
||||
- name: Install optional exFAT packages for CentOS
|
||||
shell: yum --enablerepo=li-nux-ro install exfat-utils fuse-exfat
|
||||
when: exFAT_enabled == "True" and ansible_distribution == "CentOS"
|
135
roles/2-common/tasks/xo.yml
Normal file
135
roles/2-common/tasks/xo.yml
Normal file
|
@ -0,0 +1,135 @@
|
|||
- name: XO Server specific tasks
|
||||
command: echo Starting XO.yml
|
||||
|
||||
- name: Disable sleep
|
||||
command: touch /etc/powerd/flags/inhibit-suspend
|
||||
creates=/etc/powerd/flags/inhibit-suspend
|
||||
|
||||
- name: Disable sleep on lid closing
|
||||
lineinfile: dest=/etc/powerd/powerd.conf
|
||||
regexp='^config_SLEEP_WHEN_LID_CLOSED'
|
||||
line='config_SLEEP_WHEN_LID_CLOSED="no"'
|
||||
state=present
|
||||
backup=yes
|
||||
|
||||
- name: Keep yum cache
|
||||
ini_file: dest=/etc/yum.conf
|
||||
section=main
|
||||
option=keepcache
|
||||
value=1
|
||||
when: not installing
|
||||
|
||||
- name: Keep docs when installing packages
|
||||
lineinfile: backup=yes
|
||||
dest=/etc/rpm/macros.imgcreate
|
||||
regexp='^%_excludedocs'
|
||||
state=absent
|
||||
|
||||
- name: pre-Install packages
|
||||
package: name={{ item }}
|
||||
state=latest
|
||||
with_items:
|
||||
- usbmount
|
||||
- man
|
||||
- man-db
|
||||
- man-pages
|
||||
|
||||
- name: re-Install packages
|
||||
shell: yum -y reinstall sed libidn grep which util-linux wget gnupg2 groff gnash yum
|
||||
when: not osbuilder is defined
|
||||
|
||||
- name: Configure networkmanager plugin
|
||||
ini_file: dest=/etc/NetworkManager/NetworkManager.conf
|
||||
section=main
|
||||
option=plugins
|
||||
value=ifcfg-rh,keyfile
|
||||
|
||||
- name: check for modem config file
|
||||
stat: path=/etc/NetworkManager/system-connections/"Sugar Modem Connection"
|
||||
register: config
|
||||
|
||||
- name: Change failure and interval settings for modem connection
|
||||
ini_file: dest=/etc/NetworkManager/system-connections/"Sugar Modem Connection"
|
||||
section=ppp
|
||||
option={{ item.option }}
|
||||
value={{ item.value }}
|
||||
backup=yes
|
||||
mode=0600
|
||||
with_items:
|
||||
- { option: 'lcp-echo-failure', value: '5' }
|
||||
- { option: 'lcp-echo-interval', value: '30' }
|
||||
when: config.stat.exists
|
||||
|
||||
- name: Create bigger rwtab
|
||||
lineinfile: backup=yes
|
||||
dest=/etc/sysconfig/readonly-root
|
||||
regexp='^RW_OPTIONS'
|
||||
line='RW_OPTIONS="-o size=4M -o nr_inodes=2048"'
|
||||
state=present
|
||||
|
||||
- name: Remove dhcpd entry from /etc/rwtab
|
||||
lineinfile: backup=yes
|
||||
dest=/etc/rwtab
|
||||
regexp='^empty.*/var/lib/dhcpd'
|
||||
state=absent
|
||||
|
||||
- name: Remove php entry from /etc/rwtab
|
||||
lineinfile: backup=yes
|
||||
dest=/etc/rwtab
|
||||
regexp='^empty.*/var/lib/php'
|
||||
state=absent
|
||||
|
||||
- name: Persist /etc/hosts between reboots
|
||||
lineinfile: backup=yes
|
||||
dest=/etc/statetab.d/olpc
|
||||
regexp='^/etc/hosts'
|
||||
state=absent
|
||||
|
||||
|
||||
- name: Disable /var/log tmpfs
|
||||
lineinfile: backup=yes
|
||||
dest=/etc/fstab
|
||||
regexp='^varlog.*'
|
||||
state=absent
|
||||
|
||||
- name: Enlarge the /tmp directory so that url_get does not error out
|
||||
lineinfile: backup=yes
|
||||
dest=/etc/fstab
|
||||
regexp='^/tmp*'
|
||||
line='/tmp /tmp tmpfs rw,size=600m 0 0'
|
||||
|
||||
- name: Disable graphical login
|
||||
file: path=/etc/systemd/system/default.target
|
||||
src=/lib/systemd/system/multi-user.target
|
||||
state=link
|
||||
register: disabled_login
|
||||
|
||||
- name: Remove custom profile settings
|
||||
file: path=/etc/profile.d/zzz_olpc.sh
|
||||
state=absent
|
||||
|
||||
- name: Download substitute software for i386 on FC18 XO1.5
|
||||
get_url: url="{{ xsce_download_url }}/{{ item }}" dest={{ downloads_dir}}/{{ item }}
|
||||
with_items:
|
||||
- hostapd_8188_i386
|
||||
when: wifi_id == "tplink_WM725M" and xo_model == "XO-1.5" and not {{ use_cache }} and not {{ no_network }}
|
||||
tags:
|
||||
- xo
|
||||
|
||||
- name: Put the substitute in place
|
||||
copy: src={{ downloads_dir }}/hostapd_8188_i386
|
||||
dest=/usr/sbin/hostapd
|
||||
backup=yes
|
||||
mode=0775
|
||||
owner=root
|
||||
group=root
|
||||
when: wifi_id == "tplink_WM725M" and xo_model == "XO-1.5"
|
||||
|
||||
- name: Reboot system
|
||||
command: /sbin/reboot
|
||||
when: disabled_login.changed and not installing
|
||||
ignore_errors: yes
|
||||
async: 300
|
||||
poll: 120
|
||||
|
||||
|
34
roles/2-common/tasks/xsce_ini.yml
Normal file
34
roles/2-common/tasks/xsce_ini.yml
Normal file
|
@ -0,0 +1,34 @@
|
|||
# workaround for fact that auto create does not work on ini_file
|
||||
- name: Create xsce config file
|
||||
file: dest='{{ xsce_config_file }}'
|
||||
state=touch
|
||||
|
||||
- name: Add location section to config file
|
||||
ini_file: dest='{{ xsce_config_file }}'
|
||||
section=location
|
||||
option='{{ item.option }}'
|
||||
value='{{ item.value }}'
|
||||
with_items:
|
||||
- option: 'xsce_base'
|
||||
value: '{{ xsce_base }}'
|
||||
- option: 'xsce_dir'
|
||||
value: '{{ xsce_dir }}'
|
||||
|
||||
- name: add version section
|
||||
ini_file: dest='{{ xsce_config_file }}'
|
||||
section=version
|
||||
option='{{ item.option }}'
|
||||
value='{{ item.value }}'
|
||||
with_items:
|
||||
- option: 'distribution'
|
||||
value: '{{ ansible_distribution }}'
|
||||
- option: 'arch'
|
||||
value: '{{ ansible_architecture }}'
|
||||
- option: 'xsce_branch'
|
||||
value: '{{ ansible_local["local_facts"]["xsce_branch"] }}'
|
||||
- option: 'xsce_commit'
|
||||
value: '{{ ansible_local["local_facts"]["xsce_commit"] }}'
|
||||
- option: 'install_date'
|
||||
value: '{{ ansible_date_time["iso8601"] }}'
|
||||
- option: 'install_xo'
|
||||
value: '{{ xo_model }}'
|
119
roles/2-common/tasks/yum.yml
Normal file
119
roles/2-common/tasks/yum.yml
Normal file
|
@ -0,0 +1,119 @@
|
|||
- name: install yum deps for arm!!!
|
||||
shell: dnf install -y python-urlgrabber pyxattr yum-metadata-parser
|
||||
when: ansible_distribution == "Fedora" and ansible_machine == "armv7l" and ansible_distribution_version|int >= 22
|
||||
|
||||
- name: install yum from Fedora 23 for arm!!!
|
||||
shell: dnf install -y https://kojipkgs.fedoraproject.org//packages/yum/3.4.3/506.fc23/noarch/yum-3.4.3-506.fc23.noarch.rpm python-dnf
|
||||
when: ansible_distribution == "Fedora" and ansible_machine == "armv7l" and ansible_distribution_version|int >= 22
|
||||
|
||||
- name: install yum if it has been dropped from our distribution -- Fedora 22 uses dnf!!!
|
||||
shell: dnf install -y yum
|
||||
when: ansible_distribution == "Fedora" and ansible_distribution_version|int >= 22 and ansible_machine != "armv7l"
|
||||
|
||||
- name: get the createrepo program
|
||||
package: name=createrepo
|
||||
state=present
|
||||
when: ansible_distribution != "Debian"
|
||||
|
||||
- name: Create local repo
|
||||
shell: createrepo {{ yum_packages_dir }}
|
||||
when: ansible_distribution != "Debian"
|
||||
|
||||
- name: Install local repo file.
|
||||
template: dest=/etc/yum.repos.d/xsce-local.repo
|
||||
src=local.repo
|
||||
owner=root
|
||||
mode=0644
|
||||
when: ansible_distribution != "Debian"
|
||||
|
||||
- name: Install yum packages
|
||||
package: name={{ item }}
|
||||
state=present
|
||||
with_items:
|
||||
- yum-utils
|
||||
- createrepo
|
||||
- wpa_supplicant
|
||||
- linux-firmware
|
||||
- syslog
|
||||
- xml-common
|
||||
when: ansible_distribution != "Debian"
|
||||
tags:
|
||||
- download
|
||||
|
||||
- name: Install yum packages for Debian
|
||||
package: name={{ item }}
|
||||
state=present
|
||||
with_items:
|
||||
- inetutils-syslogd
|
||||
- wpasupplicant
|
||||
when: ansible_distribution == "Debian"
|
||||
tags:
|
||||
- download
|
||||
|
||||
- name: Install common packages
|
||||
package: name={{ item }}
|
||||
state=present
|
||||
with_items:
|
||||
- acpid
|
||||
- mlocate
|
||||
- rsync
|
||||
- htop
|
||||
- etckeeper
|
||||
- python-passlib
|
||||
- usbmount
|
||||
- net-tools
|
||||
- openssh-server
|
||||
- sudo
|
||||
- logrotate
|
||||
- make
|
||||
- tar
|
||||
- unzip
|
||||
- bzip2
|
||||
- i2c-tools
|
||||
- bridge-utils
|
||||
- usbutils
|
||||
- hostapd
|
||||
- wget
|
||||
- openssl #FC 18 does not supply, but pear requires
|
||||
- gawk
|
||||
- sqlite3
|
||||
tags:
|
||||
- download
|
||||
|
||||
- name: Update common packages (not debian
|
||||
package: name={{ item }}
|
||||
state=latest
|
||||
with_items:
|
||||
- NetworkManager
|
||||
- glibc # CVE-2015-7547
|
||||
- bash
|
||||
- iptables
|
||||
when: ansible_distribution != "Debian"
|
||||
tags:
|
||||
- download
|
||||
|
||||
- name: Update common packages (debian)
|
||||
package: name={{ item }}
|
||||
state=latest
|
||||
with_items:
|
||||
- libc6
|
||||
- bash
|
||||
- iptables
|
||||
when: ansible_distribution == "Debian"
|
||||
tags:
|
||||
- download
|
||||
|
||||
|
||||
# instuctions state to start with a fully updated system before starting, stop using
|
||||
# ansible as a crutch for developers not following the directions and taking short-cuts
|
||||
|
||||
#- name: If version of Network manager has changed, subsequent nmcli commands will fail,restart now
|
||||
# service: name=NetworkManager
|
||||
# state=restarted
|
||||
# when: not installing
|
||||
# the above should use a handler - all reboots should wait until all
|
||||
# mods are preformed
|
||||
|
||||
- name: Install optional exFAT packages for CentOS
|
||||
shell: yum --enablerepo=li-nux-ro install exfat-utils fuse-exfat
|
||||
when: exFAT_enabled == "True" and ansible_distribution == "CentOS"
|
8
roles/2-common/templates/li.nux.ro.repo
Normal file
8
roles/2-common/templates/li.nux.ro.repo
Normal file
|
@ -0,0 +1,8 @@
|
|||
[li-nux-ro]
|
||||
name=RPMs missing in EPEL
|
||||
baseurl=http://li.nux.ro/download/nux/dextop/el7/x86_64/
|
||||
enabled=0
|
||||
gpgcheck=1
|
||||
gpgkey=http://li.nux.ro/download/nux/RPM-GPG-KEY-nux.ro
|
||||
|
||||
|
5
roles/2-common/templates/local.repo
Normal file
5
roles/2-common/templates/local.repo
Normal file
|
@ -0,0 +1,5 @@
|
|||
[xsce-local]
|
||||
name=xsce-local
|
||||
baseurl=file://{{ yum_packages_dir }}
|
||||
enabled=1
|
||||
gpgcheck=0
|
7
roles/2-common/templates/xsce-centos.repo
Normal file
7
roles/2-common/templates/xsce-centos.repo
Normal file
|
@ -0,0 +1,7 @@
|
|||
[xsce-centos]
|
||||
name=xsce-centos
|
||||
failovermethod=priority
|
||||
baseurl=http://download.unleashkids.org/xsce/repos/centos
|
||||
enabled=1
|
||||
metadata_expire=1d
|
||||
gpgcheck=0
|
5
roles/2-common/templates/zzz_xsce.sh
Normal file
5
roles/2-common/templates/zzz_xsce.sh
Normal file
|
@ -0,0 +1,5 @@
|
|||
# Add back sbin dirs to unprivileged users PATH
|
||||
case $PATH in
|
||||
*/sbin/*) ;;
|
||||
*) PATH=/usr/local/sbin:/usr/sbin:/sbin:$PATH ;;
|
||||
esac
|
12
roles/3-base-server/README.rst
Normal file
12
roles/3-base-server/README.rst
Normal file
|
@ -0,0 +1,12 @@
|
|||
==================
|
||||
Base Server README
|
||||
==================
|
||||
|
||||
This role is a place to aggregate roles that are required to create a basic web server.
|
||||
The functionality here is not packages that are not directly consumed by users, which are in common,
|
||||
nor specific applications, such as those found in the apps and tools roles.
|
||||
|
||||
The difference between this aggregate and server-options is that the roles here are required.
|
||||
|
||||
Eventually a graphical configuration console will be added here.
|
||||
|
4
roles/3-base-server/meta/main.yml
Normal file
4
roles/3-base-server/meta/main.yml
Normal file
|
@ -0,0 +1,4 @@
|
|||
dependencies:
|
||||
- { role: httpd, tags: ['services','httpd','base'] }
|
||||
- { role: xsce-admin, tags: ['services','xsce-admin','base'] }
|
||||
- { role: network, tags: ['services','base','network'], when: not gui_desired_network_role is defined }
|
41
roles/3-base-server/tasks/main.yml
Normal file
41
roles/3-base-server/tasks/main.yml
Normal file
|
@ -0,0 +1,41 @@
|
|||
- name: Make sure there is a content directory
|
||||
file: dest={{ doc_root }}/local_content
|
||||
state=directory
|
||||
|
||||
- name: Set up to issue warning if xsce-admin password is still default
|
||||
template: src=profile_ssh_warn.sh
|
||||
dest=/etc/profile.d/
|
||||
|
||||
- name: Is this LXDE?
|
||||
stat: path=/home/pi/.config/lxsession
|
||||
register: lx
|
||||
|
||||
- name: Do the same if running on raspbian
|
||||
template: src=lxde_ssh_warn.sh
|
||||
dest=/home/pi/.config/lxsession/LXDE-pi/
|
||||
when: lx.stat.isdir is defined and lx.stat.isdir and is_rpi and is_debian
|
||||
|
||||
- name: put a autostart line to check for default password in LXDE
|
||||
lineinfile: line=@/home/pi/.config/lxsession/LXDE-pi/lxde_ssh_warn.sh
|
||||
dest=/home/pi/.config/lxsession/LXDE-pi/autostart
|
||||
when: lx.stat.isdir is defined and lx.stat.isdir and is_rpi and is_debian
|
||||
|
||||
- name: Base Server Installed
|
||||
command: echo Base Server Installed
|
||||
|
||||
- name: Restart xsce-cmdsrv service
|
||||
service: name=xsce-cmdsrv
|
||||
state=restarted
|
||||
when: not installing
|
||||
|
||||
- name: Restart httpd
|
||||
service: name={{ apache_service }}
|
||||
state=restarted
|
||||
when: not installing
|
||||
|
||||
# If we got here we're done
|
||||
- name: Record base gui version
|
||||
lineinfile: dest=/etc/xsce/xsce.env
|
||||
regexp='^BASE_VERSION=*'
|
||||
line='BASE_VERSION="{{ gui_version }}"'
|
||||
state=present
|
22
roles/3-base-server/templates/lxde_ssh_warn.sh
Executable file
22
roles/3-base-server/templates/lxde_ssh_warn.sh
Executable file
|
@ -0,0 +1,22 @@
|
|||
#!/bin/bash
|
||||
# credit to the folks at raspberry pi foundatioon
|
||||
check_hash ()
|
||||
{
|
||||
if ! id -u xsce-admin > /dev/null 2>&1 ; then return 0 ; fi
|
||||
if grep -q "^PasswordAuthentication\s*no" /etc/ssh/sshd_config ; then return 0 ; fi
|
||||
test -x /usr/bin/mkpasswd || return 0
|
||||
SHADOW="$(sudo -n grep -E '^xsce-admin:' /etc/shadow 2>/dev/null)"
|
||||
test -n "${SHADOW}" || return 0
|
||||
if echo $SHADOW | grep -q "xsce-admin:!" ; then return 0 ; fi
|
||||
SHADOW_PW=$(echo $SHADOW | cut -d: -f2)
|
||||
if [ "$SHADOW_PW" != "\$6\$xsce51\$D.IrrEeLBYIuJkGDmi27pZUGOwPFp98qpl3hxMwWV4hXigFGmdSvy3s/j7tn6OnyTTLmlV7SsN0lCUAFzxSop." ]; then return 0 ; fi
|
||||
|
||||
if echo "${SHADOW}" | grep -q "${HASH}"; then
|
||||
zenity --warning --text="SSH is enabled and the default password for the 'xsce-admin' user has not been changed.\nThis is a security risk - please go to the xsce-console and use utilities-> change password to set a new password."
|
||||
fi
|
||||
}
|
||||
|
||||
if service ssh status | grep -q running; then
|
||||
check_hash
|
||||
fi
|
||||
unset check_hash
|
23
roles/3-base-server/templates/profile_ssh_warn.sh
Executable file
23
roles/3-base-server/templates/profile_ssh_warn.sh
Executable file
|
@ -0,0 +1,23 @@
|
|||
#!/bin/bash
|
||||
# credit to the folks at raspberry pi foundatioon
|
||||
check_hash ()
|
||||
{
|
||||
if ! id -u xsce-admin > /dev/null 2>&1 ; then return 0 ; fi
|
||||
if grep -q "^PasswordAuthentication\s*no" /etc/ssh/sshd_config ; then return 0 ; fi
|
||||
test -x /usr/bin/mkpasswd || return 0
|
||||
SHADOW="$(sudo -n grep -E '^xsce-admin:' /etc/shadow 2>/dev/null)"
|
||||
test -n "${SHADOW}" || return 0
|
||||
if echo $SHADOW | grep -q "xsce-admin:!" ; then return 0 ; fi
|
||||
SHADOW_PW=$(echo $SHADOW | cut -d: -f2)
|
||||
if [ "$SHADOW_PW" != "\$6\$xsce51\$D.IrrEeLBYIuJkGDmi27pZUGOwPFp98qpl3hxMwWV4hXigFGmdSvy3s/j7tn6OnyTTLmlV7SsN0lCUAFzxSop." ]; then return 0 ; fi
|
||||
|
||||
echo
|
||||
echo "SSH is enabled and the default password for the 'xsce-admin' user is unchanged."
|
||||
echo "This is a security risk - please login as the 'xsce-admin' user and type 'passwd' to change password."
|
||||
echo
|
||||
}
|
||||
|
||||
if /usr/sbin/service ssh status | grep -q running; then
|
||||
check_hash
|
||||
fi
|
||||
unset check_hash
|
8
roles/4-server-options/README.rst
Normal file
8
roles/4-server-options/README.rst
Normal file
|
@ -0,0 +1,8 @@
|
|||
=====================
|
||||
Server Options README
|
||||
=====================
|
||||
|
||||
This role is a place to aggregate roles that may be optionally added to the basic server,
|
||||
whereas the roles in base-server are required. As in the case of the base-server the
|
||||
functionality here is not packages that are not directly consumed by users, which are in common,
|
||||
nor specific applications, such as those found in the apps and tools roles.
|
10
roles/4-server-options/meta/main.yml
Normal file
10
roles/4-server-options/meta/main.yml
Normal file
|
@ -0,0 +1,10 @@
|
|||
dependencies:
|
||||
- { role: sshd, tags: ['services','sshd','base'] }
|
||||
- { role: network, tags: ['services','base','network'], when: gui_desired_network_role is defined }
|
||||
- { role: postgresql, tags: ['services','postgresql','base'], when: postgresql_install }
|
||||
- { role: authserver, tags: ['services','authserver','base'], when: authserver_install }
|
||||
- { role: openvpn, tags: ['options','openvpn'], when: openvpn_install }
|
||||
- { role: samba, tags: ['services','samba','options'], when: samba_install }
|
||||
- { role: usb-lib, tags: ['services','usb-lib','options'], when: usb_lib_install }
|
||||
- { role: cups, tags: ['services','cups','options'], when: cups_install }
|
||||
- { role: menu, tags: ['services','menu','options'], when: iiab_menu_install }
|
26
roles/4-server-options/tasks/main.yml
Normal file
26
roles/4-server-options/tasks/main.yml
Normal file
|
@ -0,0 +1,26 @@
|
|||
- name: Server Options Installed
|
||||
command: echo Server Options Installed
|
||||
|
||||
- name: Stop postgresql service
|
||||
command: "/etc/init.d/postgresql stop"
|
||||
ignore_errors: True
|
||||
when: postgresql_install and is_debian
|
||||
|
||||
- name: Start postgresql service
|
||||
service: name=postgresql-xs
|
||||
state=restarted
|
||||
enabled=yes
|
||||
when: postgresql_enabled
|
||||
|
||||
- name: Stop authserver service
|
||||
service: name=xs-authserver
|
||||
state=stopped
|
||||
enabled=no
|
||||
when: not authserver_enabled and authserver_install
|
||||
|
||||
- name: Start xs-authserver service
|
||||
service: name=xs-authserver
|
||||
state=restarted
|
||||
when: authserver_enabled
|
||||
|
||||
|
6
roles/5-xo-services/README.rst
Normal file
6
roles/5-xo-services/README.rst
Normal file
|
@ -0,0 +1,6 @@
|
|||
==================
|
||||
XO Services README
|
||||
==================
|
||||
|
||||
This role is a place to aggregate roles that provide XO specific services.
|
||||
|
4
roles/5-xo-services/meta/main.yml
Normal file
4
roles/5-xo-services/meta/main.yml
Normal file
|
@ -0,0 +1,4 @@
|
|||
dependencies:
|
||||
- { role: ejabberd, tags: ['olpc','ejabberd','xo-services'], when: ejabberd_install }
|
||||
- { role: idmgr, tags: ['olpc','idmgr','xo-services'], when: idmgr_install }
|
||||
- { role: activity-server, tags: ['olpc','activity-server','xo-services'], when: activity_server_install }
|
3
roles/5-xo-services/tasks/main.yml
Normal file
3
roles/5-xo-services/tasks/main.yml
Normal file
|
@ -0,0 +1,3 @@
|
|||
- name: XO Services Installed
|
||||
command: echo XO Services Installed
|
||||
|
7
roles/6-generic-apps/README.rst
Normal file
7
roles/6-generic-apps/README.rst
Normal file
|
@ -0,0 +1,7 @@
|
|||
===================
|
||||
Generic Apps README
|
||||
===================
|
||||
|
||||
This role is a place to aggregate roles that install apps of a more generic nature, as opposed to educational or managment.
|
||||
Content Management Systems or Chat or Wiki applications would go here.
|
||||
|
7
roles/6-generic-apps/meta/main.yml
Normal file
7
roles/6-generic-apps/meta/main.yml
Normal file
|
@ -0,0 +1,7 @@
|
|||
dependencies:
|
||||
- { role: mysql, tags: ['generic','mysql'], when: mysql_install }
|
||||
- { role: elgg, tags: ['generic','elgg'], when: elgg_install }
|
||||
- { role: owncloud, tags: ['generic','owncloud'], when: owncloud_install }
|
||||
- { role: dokuwiki, tags: ['generic','dokuwiki'], when: dokuwiki_install }
|
||||
- { role: wordpress, tags: ['generic','wordpress'], when: wordpress_install }
|
||||
- { role: calibre, tags: ['generic','calibre'], when: calibre_install }
|
3
roles/6-generic-apps/tasks/main.yml
Normal file
3
roles/6-generic-apps/tasks/main.yml
Normal file
|
@ -0,0 +1,3 @@
|
|||
- name: Generic Apps Installed
|
||||
command: echo Generic Apps Installed
|
||||
|
6
roles/7-edu-apps/README.rst
Normal file
6
roles/7-edu-apps/README.rst
Normal file
|
@ -0,0 +1,6 @@
|
|||
===================================
|
||||
Educational Apps and Content README
|
||||
===================================
|
||||
|
||||
This role is a place to aggregate roles that provide Educational Content or
|
||||
are specifically targetted at pedagogical activities.
|
9
roles/7-edu-apps/meta/main.yml
Normal file
9
roles/7-edu-apps/meta/main.yml
Normal file
|
@ -0,0 +1,9 @@
|
|||
dependencies:
|
||||
- { role: moodle, tags: ['olpc','moodle','edu-apps'], when: moodle_install }
|
||||
- { role: iiab, tags: ['iiab','edu-apps'], when: iiab_install }
|
||||
- { role: pathagar, tags: ['pathagar','edu-apps'], when: pathagar_install }
|
||||
- { role: rachel, tags: ['rachel','edu-apps'], when: rachel_install }
|
||||
- { role: kalite, tags: ['kalite','edu-apps'], when: kalite_install }
|
||||
- { role: kiwix, tags: ['kiwix','edu-apps'], when: kiwix_install }
|
||||
- { role: sugarizer, tags: ['sugarizer','edu-apps'], when: sugarizer_install }
|
||||
- { role: debian_schooltool, tags: ['schooltool','debian_schooltool','edu-apps'], when: debian_schooltool_install and is_debian }
|
3
roles/7-edu-apps/tasks/main.yml
Normal file
3
roles/7-edu-apps/tasks/main.yml
Normal file
|
@ -0,0 +1,3 @@
|
|||
- name: Educational Apps and Content Installed
|
||||
command: echo Educational Apps and Content Installed
|
||||
|
6
roles/8-mgmt-tools/README.rst
Normal file
6
roles/8-mgmt-tools/README.rst
Normal file
|
@ -0,0 +1,6 @@
|
|||
======================================
|
||||
Assessment and Monitoring Tools README
|
||||
======================================
|
||||
|
||||
This role is a place to aggregate roles that provide tools for Administering and
|
||||
Monitoring the Server and for Assessing its use and effectiveness.
|
10
roles/8-mgmt-tools/meta/main.yml
Normal file
10
roles/8-mgmt-tools/meta/main.yml
Normal file
|
@ -0,0 +1,10 @@
|
|||
dependencies:
|
||||
- { role: sugar-stats, tags: ['olpc','sugar-stats','tools'], when: sugar_stats_install and ansible_distribution != "CentOS" }
|
||||
# - { role: ajenti, tags: ['services','ajenti','tools'], when: ajenti_install }
|
||||
- { role: munin, tags: ['services','munin','tools'], when: munin_install }
|
||||
- { role: monit, tags: ['services','monit','tools'], when: monit_install }
|
||||
- { role: vnstat, tags: ['services','vnstat','tools'], when: vnstat_install }
|
||||
- { role: xovis, tags: ['services','xovis','tools'], when: xovis_install and ansible_distribution != "CentOS" }
|
||||
- { role: phpmyadmin, tags: ['services','phpmyadmin','tools'], when: phpmyadmin_install }
|
||||
- { role: awstats, tags: ['services','awstats','tools'], when: awstats_install }
|
||||
- { role: teamviewer, tags: ['services','teamviewer','tools'], when: teamviewer_install }
|
3
roles/8-mgmt-tools/tasks/main.yml
Normal file
3
roles/8-mgmt-tools/tasks/main.yml
Normal file
|
@ -0,0 +1,3 @@
|
|||
- name: Assessment and Monitoring Tools Installed
|
||||
command: echo Assessment and Monitoring Tools Installed
|
||||
|
21
roles/9-local-addons/README.rst
Normal file
21
roles/9-local-addons/README.rst
Normal file
|
@ -0,0 +1,21 @@
|
|||
===================
|
||||
Local Addons README
|
||||
===================
|
||||
|
||||
This role is a place to aggregate roles developed by various contributors or locally developed.
|
||||
|
||||
Development
|
||||
-----------
|
||||
|
||||
Create the role you wish to add to the XSCE School Server by following the pattern of another role or any other means.
|
||||
|
||||
Packaging
|
||||
---------
|
||||
|
||||
Add your role into the main.yml file in the meta directory of the 7-local-addons role. It will now get installed as part of
|
||||
the next ansible run.
|
||||
|
||||
More Info
|
||||
---------
|
||||
|
||||
Have a look at the docs section of this git repo for more detailed information.
|
3
roles/9-local-addons/meta/main.yml
Normal file
3
roles/9-local-addons/meta/main.yml
Normal file
|
@ -0,0 +1,3 @@
|
|||
# Add your role to this list and then uncomment dependencies. Adding a tag is handy for testing.
|
||||
#dependencies:
|
||||
|
3
roles/9-local-addons/tasks/main.yml
Normal file
3
roles/9-local-addons/tasks/main.yml
Normal file
|
@ -0,0 +1,3 @@
|
|||
- name: Addon services installed
|
||||
command: echo Addon services installed
|
||||
|
139
roles/activity-server/README.rst
Normal file
139
roles/activity-server/README.rst
Normal file
|
@ -0,0 +1,139 @@
|
|||
Serve XO activities from the XS school server
|
||||
=============================================
|
||||
|
||||
XO laptops can update their activities via HTTP, using specially
|
||||
microformatted html pages to determine what to download.
|
||||
|
||||
This package imports XO activities from a USB stick and generates the
|
||||
correct html to serve them, in as many languages as it knows how,
|
||||
using the localisation information from the activity bundles. Content
|
||||
negotiation between Apache and the laptops decides what html is seen.
|
||||
|
||||
The URL for this index is http://schoolserver/activities/.
|
||||
|
||||
A facility exists to add extra descriptive html to the generated
|
||||
indexes.
|
||||
|
||||
USB import
|
||||
----------
|
||||
|
||||
When a USB drive is inserted, the server looks for a directory in the
|
||||
root directory called xs-activity-server. In there it expects to find
|
||||
any number of activity bundles, a file called manifest.sha1, and
|
||||
optionally a file or files with the suffix ".info". Depending on the
|
||||
configuration of the school server, a file called "manifest.sha1.sig"
|
||||
might also be required.
|
||||
|
||||
Activity bundles are zip files with the suffix .xo and an internal
|
||||
layout described at http://wiki.laptop.org/go/Activity_bundles.
|
||||
|
||||
The manifest file should contain sha1sums for each activity bundle and
|
||||
the metadata files, as if you had run
|
||||
|
||||
sha1sum *.xo *.info > manifest.sha1
|
||||
|
||||
in the directory.
|
||||
|
||||
If full XS security is enabled (by the presence of /etc/xs-security-on
|
||||
-- see the xs-tools documentation), then manifest.sha1.sig should
|
||||
contain a detached GPG signature for manifest.sha1, signed by a key
|
||||
that the XS knows. If the school server lacks the /etc/xs-security-on
|
||||
flag, the manifest.sha1.sig file is ignored.
|
||||
|
||||
Multiple languages
|
||||
------------------
|
||||
|
||||
Activities can contain localisation information, which usually
|
||||
consists of a translated activity name. The localised information is
|
||||
found in the bundle in a directory like:
|
||||
|
||||
SomeWonderful.activity/locale/pt-BR/activity.linfo
|
||||
|
||||
where pt-BR is an RFC1788 language code. If any activity contains an
|
||||
activity.linfo file for a language, then an index is generated. The
|
||||
server has templates for indexes in some languages (currently Spanish
|
||||
and English); for other languages the indexes will be in English
|
||||
except for the localised names.
|
||||
|
||||
These index files are saved with names like
|
||||
activities/index.html.zh-es. You can choose to look at them directly
|
||||
that way, or let your browser decide which one is best for you by
|
||||
visiting activities/index.html.
|
||||
|
||||
If some activities lack localised information for a multi-part
|
||||
language code, the index will include information that exists for the
|
||||
corresponding single part code, before defaulting to English. For
|
||||
example, a zh-CN page will include zh localisation if need be. (This
|
||||
may not always be the best result: bn and bn-IN appear to use
|
||||
different scripts).
|
||||
|
||||
|
||||
Including extra descriptions
|
||||
----------------------------
|
||||
|
||||
The optional .info files in the xs-activation-server directory should
|
||||
consist of sections in this format:
|
||||
|
||||
[com.microsoft.Word]
|
||||
description = Write replacement, without distraction of collaboration.
|
||||
|
||||
[some.other.Something]
|
||||
description = another description, all on one line.
|
||||
|
||||
If a section heading (in square brackets) matches the bundle_id or
|
||||
service_name of an activity, the description will be displayed on the
|
||||
generated html page. This information is not used by automatic
|
||||
updates, but it might assist children in browsing and manually
|
||||
installing activities. Note: there is no clever localisation here.
|
||||
|
||||
Multiple versions
|
||||
-----------------
|
||||
|
||||
Over the course of a server deployment, an activity might be updated
|
||||
several times. To preserve disk space, only the 4 most recent
|
||||
versions of an activity are kept. Links to the second, third and
|
||||
fourth newest versions are presented in the activities html file, but
|
||||
these do not use the activity microformat and will not be visible to
|
||||
automated updaters.
|
||||
|
||||
To determine which activities are the most recent, the file's modification
|
||||
times (mtime) are examined. The version number is not considered here.
|
||||
|
||||
Note: If you plug in a USB stick with very out-of-date activities they
|
||||
will be deleted as soon as they get on the server.
|
||||
|
||||
HTML microformat
|
||||
----------------
|
||||
|
||||
The microformat is described at
|
||||
http://wiki.laptop.org/go/Activity_microformat.
|
||||
|
||||
Utility script
|
||||
--------------
|
||||
|
||||
/usr/bin/xs-check-activities will print statistics about a directory
|
||||
of activities to stderr. Its output is not particularly well
|
||||
formatted or explained, but it is there if you want it.
|
||||
|
||||
Files and directories
|
||||
---------------------
|
||||
|
||||
Activities are stored in /library/xs-activity-server/activities, with
|
||||
the html index being index.html in that directory. Apache is coaxed
|
||||
into serving this by /etc/httpd/conf.d/xs-activity-server.conf.
|
||||
|
||||
Bugs
|
||||
----
|
||||
|
||||
Old versions are only saved if the different versions have different
|
||||
file names. Most activity bundles have names like 'Maze-4.xo',
|
||||
'Maze-5.xo' and so on, but some lack the version number in the file
|
||||
name, so the most recently imported version ends up overwriting the
|
||||
older ones.
|
||||
|
||||
Source
|
||||
------
|
||||
|
||||
This role is based on the xs-activity-server rpm.
|
||||
|
||||
http://dev.laptop.org/git/users/martin/xs-activity-server/ v0.4 release
|
3
roles/activity-server/defaults/main.yml
Normal file
3
roles/activity-server/defaults/main.yml
Normal file
|
@ -0,0 +1,3 @@
|
|||
activity_server_enabled: False
|
||||
activity_server_install: True
|
||||
|
30
roles/activity-server/files/bin/xs-check-activities
Normal file
30
roles/activity-server/files/bin/xs-check-activities
Normal file
|
@ -0,0 +1,30 @@
|
|||
#!/usr/bin/python
|
||||
# Copyright (C) 2008 One Laptop Per Child Association, Inc.
|
||||
# Licensed under the terms of the GNU GPL v2 or later; see COPYING for details.
|
||||
#
|
||||
# written by Douglas Bagnall <douglas@paradise.net.nz>
|
||||
|
||||
"""This script reads activity.info from bundle files and reports on
|
||||
their quality.
|
||||
"""
|
||||
|
||||
import xs_activities
|
||||
import sys, os
|
||||
|
||||
xs_activities.USE_STDERR = True
|
||||
|
||||
show_all = '--show-all' in sys.argv
|
||||
if show_all:
|
||||
sys.argv.remove('--show-all')
|
||||
|
||||
|
||||
try:
|
||||
directory = sys.argv[1]
|
||||
os.stat(directory)
|
||||
except (IndexError, OSError):
|
||||
print __doc__
|
||||
print "USAGE: %s DIRECTORY" % sys.argv[0]
|
||||
sys.exit(1)
|
||||
|
||||
xs_activities.check_all_bundles(directory, show_all)
|
||||
|
93
roles/activity-server/files/bin/xs-regenerate-activities
Normal file
93
roles/activity-server/files/bin/xs-regenerate-activities
Normal file
|
@ -0,0 +1,93 @@
|
|||
#!/usr/bin/python
|
||||
# Copyright (C) 2008 One Laptop Per Child Association, Inc.
|
||||
# Licensed under the terms of the GNU GPL v2 or later; see COPYING for details.
|
||||
#
|
||||
# written by Douglas Bagnall <douglas@paradise.net.nz>
|
||||
|
||||
"""Read activity.info files from a directory full of activity bundles
|
||||
and write an appropriate html manifest of the most recent versions.
|
||||
The manifest uses the OLPC activity microformat:
|
||||
|
||||
http://wiki.laptop.org/go/Activity_microformat
|
||||
|
||||
This is put in a place where apache can find it, and apache will serve
|
||||
it and the activities to the laptops. Messages go to /var/log/user.log.
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import shutil
|
||||
from time import time
|
||||
|
||||
import xs_activities
|
||||
|
||||
INPUT_DIR = "/library/xs-activity-server/activities"
|
||||
OUTPUT_LINK = "/library/xs-activity-server/www"
|
||||
|
||||
try:
|
||||
CURRENT_DIR = os.readlink(OUTPUT_LINK)
|
||||
except OSError:
|
||||
CURRENT_DIR = None
|
||||
|
||||
|
||||
def create_dir_manifest(dir_path):
|
||||
manifest = []
|
||||
os.chdir(dir_path)
|
||||
for root, dirs, files in os.walk("."):
|
||||
for filename in files:
|
||||
if not filename.endswith(".xo") and not filename.endswith(".xol"):
|
||||
continue
|
||||
|
||||
path = os.path.join(root, filename)
|
||||
s = os.stat(path)
|
||||
manifest.append((path, s.st_ino))
|
||||
|
||||
manifest.sort()
|
||||
return manifest
|
||||
|
||||
|
||||
def input_changed():
|
||||
if CURRENT_DIR is None:
|
||||
return True
|
||||
|
||||
input_manifest = create_dir_manifest(INPUT_DIR)
|
||||
current_manifest = create_dir_manifest(CURRENT_DIR)
|
||||
return input_manifest != current_manifest
|
||||
|
||||
|
||||
if not input_changed():
|
||||
# no changes or nothing to do
|
||||
sys.exit(0)
|
||||
|
||||
# create new output dir
|
||||
OUTPUT_DIR = OUTPUT_LINK + "." + str(time())
|
||||
os.mkdir(OUTPUT_DIR)
|
||||
|
||||
# link in all activities
|
||||
os.chdir(INPUT_DIR)
|
||||
for root, dirs, files in os.walk("."):
|
||||
output_dir = os.path.join(OUTPUT_DIR, root)
|
||||
if not os.path.isdir(output_dir):
|
||||
os.makedirs(output_dir)
|
||||
|
||||
for filename in files:
|
||||
if not filename.endswith(".xo") and not filename.endswith(".xol"):
|
||||
continue
|
||||
|
||||
path = os.path.join(root, filename)
|
||||
output_path = os.path.join(output_dir, filename)
|
||||
os.link(path, output_path)
|
||||
|
||||
# create html index
|
||||
output_html = os.path.join(output_dir, 'index.html')
|
||||
xs_activities.htmlise_bundles(output_dir, output_html)
|
||||
|
||||
|
||||
# update symlink atomically
|
||||
link = OUTPUT_DIR + ".lnk"
|
||||
os.symlink(OUTPUT_DIR, link)
|
||||
os.rename(link, OUTPUT_LINK)
|
||||
|
||||
# remove old index
|
||||
if CURRENT_DIR is not None:
|
||||
shutil.rmtree(CURRENT_DIR, ignore_errors=True)
|
10
roles/activity-server/files/lang_templates/en/activity
Normal file
10
roles/activity-server/files/lang_templates/en/activity
Normal file
|
@ -0,0 +1,10 @@
|
|||
<div class="olpc-activity-info">
|
||||
<h2>%(name)s</h2>
|
||||
%(description)s
|
||||
<ul>
|
||||
<li>Identifier: <span class="olpc-activity-id">%(bundle_id)s</span></li>
|
||||
<li>Version: <span class="olpc-activity-version">%(activity_version)s</span></li>
|
||||
<li>URL: <span class="olpc-activity-url"><a href="%(bundle_url)s">%(bundle_url)s</a></span></li>
|
||||
<li style="display: %(show_older_versions)s">Older versions: %(older_versions)s</li>
|
||||
</ul>
|
||||
</div>
|
7
roles/activity-server/files/lang_templates/en/page
Normal file
7
roles/activity-server/files/lang_templates/en/page
Normal file
|
@ -0,0 +1,7 @@
|
|||
<html>
|
||||
<body>
|
||||
<h1 id="olpc-activity-group-name">Locally available activities</h1>
|
||||
<p id="olpc-activity-group-desc">These activities are stored on the school server.</p>
|
||||
%(activities)s
|
||||
</body>
|
||||
</html>
|
10
roles/activity-server/files/lang_templates/es/activity
Normal file
10
roles/activity-server/files/lang_templates/es/activity
Normal file
|
@ -0,0 +1,10 @@
|
|||
<div class="olpc-activity-info">
|
||||
<h2>%(name)s</h2>
|
||||
%(description)s
|
||||
<ul>
|
||||
<li>Identificador: <span class="olpc-activity-id">%(bundle_id)s</span></li>
|
||||
<li>Versión: <span class="olpc-activity-version">%(activity_version)s</span></li>
|
||||
<li>URL: <span class="olpc-activity-url"><a href="%(bundle_url)s">%(bundle_url)s</a></span></li>
|
||||
<li style="display: %(show_older_versions)s">Versiones anteriores: %(older_versions)s</li>
|
||||
</ul>
|
||||
</div>
|
8
roles/activity-server/files/lang_templates/es/page
Normal file
8
roles/activity-server/files/lang_templates/es/page
Normal file
|
@ -0,0 +1,8 @@
|
|||
<!DOCTYPE html>
|
||||
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<body>
|
||||
<h1 id="olpc-activity-group-name">Actividades disponibles localmente</h1>
|
||||
<p id="olpc-activity-group-desc">Estas actividades están almacenads en el servidor de la escuela.</p>
|
||||
%(activities)s
|
||||
</body>
|
||||
</html>
|
10
roles/activity-server/files/lang_templates/fr/activity
Normal file
10
roles/activity-server/files/lang_templates/fr/activity
Normal file
|
@ -0,0 +1,10 @@
|
|||
<div class="olpc-activity-info">
|
||||
<h2>%(name)s</h2>
|
||||
%(description)s
|
||||
<ul>
|
||||
<li>Identifiant: <span class="olpc-activity-id">%(bundle_id)s</span></li>
|
||||
<li>Version: <span class="olpc-activity-version">%(activity_version)s</span></li>
|
||||
<li>URL: <span class="olpc-activity-url"><a href="%(bundle_url)s">%(bundle_url)s</a></span></li>
|
||||
<li style="display: %(show_older_versions)s">Anciennes versions: %(older_versions)s</li>
|
||||
</ul>
|
||||
</div>
|
8
roles/activity-server/files/lang_templates/fr/page
Normal file
8
roles/activity-server/files/lang_templates/fr/page
Normal file
|
@ -0,0 +1,8 @@
|
|||
<!DOCTYPE html>
|
||||
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<body>
|
||||
<h1 id="olpc-activity-group-name">Activités disponibles localement</h1>
|
||||
<p id="olpc-activity-group-desc">Ces activités sont stockées sur le serveur de l’école.</p>
|
||||
%(activities)s
|
||||
</body>
|
||||
</html>
|
10
roles/activity-server/files/lang_templates/ht/activity
Normal file
10
roles/activity-server/files/lang_templates/ht/activity
Normal file
|
@ -0,0 +1,10 @@
|
|||
<div class="olpc-activity-info">
|
||||
<h2>%(name)s</h2>
|
||||
%(description)s
|
||||
<ul>
|
||||
<li>Pou idantifye: <span class="olpc-activity-id">%(bundle_id)s</span></li>
|
||||
<li>Vesyon: <span class="olpc-activity-version">%(activity_version)s</span></li>
|
||||
<li>URL: <span class="olpc-activity-url"><a href="%(bundle_url)s">%(bundle_url)s</a></span></li>
|
||||
<li style="display: %(show_older_versions)s">Vesyon ansyen: %(older_versions)s</li>
|
||||
</ul>
|
||||
</div>
|
8
roles/activity-server/files/lang_templates/ht/page
Normal file
8
roles/activity-server/files/lang_templates/ht/page
Normal file
|
@ -0,0 +1,8 @@
|
|||
<!DOCTYPE html>
|
||||
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<body>
|
||||
<h1 id="olpc-activity-group-name">Aktivite ki disponib nan Bwat la</h1>
|
||||
<p id="olpc-activity-group-desc">Aktivite sa yo disponib sou sit lekòl la.</p>
|
||||
%(activities)s
|
||||
</body>
|
||||
</html>
|
10
roles/activity-server/files/www.0/index.html.en
Normal file
10
roles/activity-server/files/www.0/index.html.en
Normal file
|
@ -0,0 +1,10 @@
|
|||
<html>
|
||||
<body>
|
||||
<h1 id="olpc-activity-group-name">Locally available activities</h1>
|
||||
<p id="olpc-activity-group-desc">These activities are stored on the school server.</p>
|
||||
<div class="olpc-activity-info">
|
||||
There are currently no activities. Insert a USB drive with activities on it to add some.
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
11
roles/activity-server/files/www.0/index.html.fr
Normal file
11
roles/activity-server/files/www.0/index.html.fr
Normal file
|
@ -0,0 +1,11 @@
|
|||
<!DOCTYPE html>
|
||||
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<body>
|
||||
<h1 id="olpc-activity-group-name">Activités disponibles localement</h1>
|
||||
<p id="olpc-activity-group-desc">Ces activités sont stockées sur le serveur de l’école.</p>
|
||||
<div class="olpc-activity-info">
|
||||
Il n'y a pas d'activités. Insérez une clé USB avec des activités sur pour ajouter.
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
11
roles/activity-server/files/www.0/index.html.ht
Normal file
11
roles/activity-server/files/www.0/index.html.ht
Normal file
|
@ -0,0 +1,11 @@
|
|||
<!DOCTYPE html>
|
||||
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<body>
|
||||
<h1 id="olpc-activity-group-name">Aktivite ki disponib nan Bwat la</h1>
|
||||
<p id="olpc-activity-group-desc">Aktivite sa yo disponib sou sit lekòl la.</p>
|
||||
<div class="olpc-activity-info">
|
||||
Gen kounye a pa gen okenn aktivite. Antre yon USB ak aktivite sou li ajoute kèk.
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
535
roles/activity-server/files/xs_activities/__init__.py
Normal file
535
roles/activity-server/files/xs_activities/__init__.py
Normal file
|
@ -0,0 +1,535 @@
|
|||
# Copyright (C) 2008 One Laptop Per Child Association, Inc.
|
||||
# Licensed under the terms of the GNU GPL v2 or later; see COPYING for details.
|
||||
#
|
||||
# written by Douglas Bagnall <douglas@paradise.net.nz>
|
||||
|
||||
"""Functions for processing XO activities, either for indexing and
|
||||
presentaton to the laptops, or for diagnostics.
|
||||
"""
|
||||
|
||||
import os, sys, shutil
|
||||
import zipfile
|
||||
import re
|
||||
from cStringIO import StringIO
|
||||
#import traceback
|
||||
import syslog
|
||||
from ConfigParser import SafeConfigParser
|
||||
|
||||
# we no longer really have a default in that it is set in the conf file
|
||||
# we assume that we have a lang_template for the default language
|
||||
TEMPLATE_DIR = '/library/xs-activity-server/lang_templates'
|
||||
DEFAULT_LANG = 'en'
|
||||
|
||||
# how many versions before the latest are worth having around.
|
||||
KEEP_OLD_VERSIONS = 3
|
||||
|
||||
#print to stderr, rathe than syslog?
|
||||
USE_STDERR=False
|
||||
|
||||
REQUIRED_TAGS = ('bundle_id', 'activity_version', 'host_version', 'name', 'license')
|
||||
OPTIONAL_TAGS = ('show_launcher', 'exec', 'mime_types', 'icon')
|
||||
#XXX need either icon or show_launcher=no
|
||||
|
||||
def log(msg, level=syslog.LOG_NOTICE):
|
||||
if USE_STDERR:
|
||||
print >> sys.stderr, msg
|
||||
else:
|
||||
syslog.openlog( 'xs-activity-server', 0, syslog.LOG_USER )
|
||||
syslog.syslog(level, msg)
|
||||
syslog.closelog()
|
||||
|
||||
class BundleError(Exception):
|
||||
pass
|
||||
|
||||
class Bundle(object):
|
||||
def __init__(self, bundle):
|
||||
self.linfo = {}
|
||||
self.zf = zipfile.ZipFile(bundle)
|
||||
# The activity path will be 'Something.activity/activity/activity.info'
|
||||
for p in self.zf.namelist():
|
||||
if p.endswith(self.INFO_PATH):
|
||||
self.raw_data = read_info_file(self.zf, p, self.INFO_SECTION)
|
||||
|
||||
# the file name itself is needed for the URL
|
||||
self.url = os.path.basename(bundle)
|
||||
self.mtime = os.stat(bundle).st_mtime
|
||||
|
||||
self.name = self.raw_data.get('name')
|
||||
self.license = self.raw_data.get('license', None)
|
||||
|
||||
# child ctor should now call
|
||||
# _set_bundle_id
|
||||
# _set_version
|
||||
# _set_description
|
||||
def _set_bundle_id(self, id):
|
||||
if id is None:
|
||||
raise BundleError("bad bundle: No bundle ID")
|
||||
self.bundle_id = id
|
||||
if self.name is None:
|
||||
self.name = id
|
||||
|
||||
def _set_version(self, version):
|
||||
self.version = version
|
||||
|
||||
def _set_description(self, description):
|
||||
self.description = description
|
||||
|
||||
def __cmp__(self, other):
|
||||
"""Alphabetical sort (locale dependant of course)"""
|
||||
if self.bundle_id == other.bundle_id:
|
||||
return cmp(self.version, other.version)
|
||||
return cmp(self.name, other.name)
|
||||
|
||||
def set_older_versions(self, versions):
|
||||
"""Versions should be a list of (version number, version tuples)"""
|
||||
self.older_versions = ', '.join('<a href="%s">%s</a>' % (v.url, v.version) for v in versions)
|
||||
|
||||
def to_html(self, locale, template=None):
|
||||
"""Fill in the template with data approriate for the locale."""
|
||||
if template is None:
|
||||
template = read_template('activity', locale)
|
||||
|
||||
d = {'older_versions': self.older_versions,
|
||||
'bundle_id': self.bundle_id,
|
||||
'activity_version': self.version,
|
||||
'bundle_url': self.url,
|
||||
'name': self.name,
|
||||
'description': self.description,
|
||||
}
|
||||
|
||||
d.update(self.linfo.get(locale, {}))
|
||||
|
||||
if d['older_versions']:
|
||||
d['show_older_versions'] = 'inline'
|
||||
else:
|
||||
d['show_older_versions'] = 'none'
|
||||
|
||||
return template % d
|
||||
|
||||
def get_name(self, locale=None):
|
||||
return self.name
|
||||
|
||||
class Content(Bundle):
|
||||
INFO_PATH = "library/library.info"
|
||||
INFO_SECTION = "Library"
|
||||
|
||||
def __init__(self, bundle):
|
||||
super(Content, self).__init__(bundle)
|
||||
|
||||
d = self.raw_data
|
||||
# bundle_id is often missing; service name is used instead.
|
||||
self._set_bundle_id(d.get('global_name', None))
|
||||
self._set_version(d.get('library_version', 1))
|
||||
self._set_description(d.get('long_name', ''))
|
||||
|
||||
def debug(self, force_recheck=False):
|
||||
# FIXME: implement debug checking for content bundles
|
||||
return {}
|
||||
|
||||
class Activity(Bundle):
|
||||
INFO_PATH = "activity/activity.info"
|
||||
INFO_SECTION = "Activity"
|
||||
|
||||
#Activities appear to be looser than RFC3066, using e.g. _ in place of -.
|
||||
linfo_re = re.compile(r'/locale/([A-Za-z]+[\w-]*)/activity.linfo$')
|
||||
|
||||
def __init__(self, bundle):
|
||||
"""Takes a zipped .xo bundle name, returns a dictionary of its
|
||||
activity info. Can raise a variety of exceptions, all of
|
||||
which should indicate the bundle is invalid."""
|
||||
super(Activity, self).__init__(bundle)
|
||||
|
||||
# The locale info will be Something.activity/locale/xx_XX/activity.linfo
|
||||
for p in self.zf.namelist():
|
||||
linfo = self.linfo_re.search(p)
|
||||
if linfo:
|
||||
lang = canonicalise(linfo.group(1))
|
||||
self.linfo[lang] = read_info_file(self.zf, p, self.INFO_SECTION)
|
||||
|
||||
# Unfortunately the dictionary lacks some information, and
|
||||
# stores other bits in inconsistent ways.
|
||||
|
||||
d = self.raw_data
|
||||
# bundle_id is often missing; service name is used instead.
|
||||
self._set_bundle_id(d.get('bundle_id', d.get('service_name')))
|
||||
self._set_version(d.get('activity_version', 1))
|
||||
self._set_description(d.get('description', ''))
|
||||
|
||||
def debug(self, force_recheck=False):
|
||||
"""Make a copy of the raw data with added bits so we can work
|
||||
out what is going on. This is useful for diagnosing problems
|
||||
with odd activities and composing tut-tut-ing emails to their
|
||||
authors.
|
||||
|
||||
Not used in production."""
|
||||
if hasattr(self, '_debug_data') and not force_recheck:
|
||||
return self._debug_data
|
||||
|
||||
d = self.raw_data.copy()
|
||||
|
||||
correct_forms = {
|
||||
'name': str.upper,
|
||||
'activity_version': str.isdigit,
|
||||
'host_version': str.isdigit,
|
||||
'bundle_id': re.compile(r'^[\w.]+$').match,
|
||||
'service_name': re.compile(r'^[\w.]+$').match,
|
||||
'icon': re.compile(r'^[\S]+$').match,
|
||||
'exec': str.upper,
|
||||
'mime_types': re.compile(r'^([\w.+-]+/[\w.+-]+;?)*$').match,
|
||||
'update_url': re.compile(r'^http://([\w-]+\.?)+(:\d+)?(/[\w~%.-]+)*$').match,
|
||||
#'update_url': re.compile(r'^$').match,
|
||||
'show_launcher': re.compile(r'^(yes)|(no)$').match,
|
||||
'class': re.compile(r'^(\w+.?)+$').match,
|
||||
'license': str.upper,
|
||||
#'license': re.compile(r'^GPLv[23]\+?$').match,
|
||||
}
|
||||
|
||||
for k, v in d.items():
|
||||
if k in correct_forms:
|
||||
f = correct_forms.get(k, len)
|
||||
if not f(v):
|
||||
d['BAD ' + k] = v
|
||||
|
||||
rcount = 0
|
||||
for k in REQUIRED_TAGS:
|
||||
if k not in d:
|
||||
d['LACKS %s' % k] = True
|
||||
rcount += 1
|
||||
d['MISSING KEYS'] = rcount
|
||||
|
||||
for t in OPTIONAL_TAGS:
|
||||
if t not in d:
|
||||
d['NO ' + t] = True
|
||||
|
||||
if not 'icon' in d and d.get('show_launcher') != 'no':
|
||||
d['NO icon AND show_launcher'] = True
|
||||
|
||||
self._debug_data = d
|
||||
return d
|
||||
|
||||
def get_name(self, locale):
|
||||
"""Return the best guess at a name for the locale."""
|
||||
for loc in locale_search_path(locale):
|
||||
if loc in self.linfo and 'name' in self.linfo[loc]:
|
||||
return self.linfo[loc]['name']
|
||||
return super(Activity, self).get_name()
|
||||
|
||||
|
||||
|
||||
def check_all_bundles(directory, show_all_bundles=False):
|
||||
"""A verbose debug function."""
|
||||
all_bundles = []
|
||||
unique_bundles = {}
|
||||
counts = {}
|
||||
# watch for these tags and print out the lists
|
||||
bad_contents = {}
|
||||
all_linfo = {}
|
||||
unique_linfo = {}
|
||||
linfo_keys = {}
|
||||
log('Checking all activities in %s\n' % directory)
|
||||
for f in os.listdir(directory):
|
||||
if not f.endswith('.xo') and not f.endswith('.xol'):
|
||||
continue
|
||||
#log(f)
|
||||
try:
|
||||
if f.endswith('.xo'):
|
||||
bundle = Activity(os.path.join(directory, f))
|
||||
else:
|
||||
bundle = Content(os.path.join(directory, f))
|
||||
except Exception, e:
|
||||
log("IRREDEEMABLE bundle %-25s (Error: %s)" % (f, e), syslog.LOG_WARNING)
|
||||
|
||||
#Clump together bundles of the same ID
|
||||
x = unique_bundles.setdefault(bundle.bundle_id, [])
|
||||
x.append(bundle)
|
||||
all_bundles.append(bundle)
|
||||
|
||||
if not show_all_bundles:
|
||||
#only show the newest one of each set.
|
||||
bundles = []
|
||||
for versions in unique_bundles.values():
|
||||
versions.sort()
|
||||
bundles.append(versions[-1])
|
||||
|
||||
else:
|
||||
bundles = all_bundles
|
||||
|
||||
licenses = {}
|
||||
for bundle in bundles:
|
||||
bid = bundle.bundle_id
|
||||
for k, v in bundle.debug().iteritems():
|
||||
counts[k] = counts.get(k, 0) + 1
|
||||
if k.startswith('BAD '):
|
||||
bc = bad_contents.setdefault(k, {})
|
||||
bc[bid] = v
|
||||
for k, v in bundle.linfo.iteritems():
|
||||
linfo_l = all_linfo.setdefault(k, [])
|
||||
linfo_l.append(bundle)
|
||||
for x in v:
|
||||
linfo_keys[x] = linfo_keys.get(x, 0) + 1
|
||||
if v['name'] != bundle.name:
|
||||
linfo_l = unique_linfo.setdefault(k, [])
|
||||
linfo_l.append(bundle)
|
||||
|
||||
if bundle.license:
|
||||
lic = licenses.setdefault(bundle.license, [])
|
||||
lic.append(bundle.bundle_id)
|
||||
|
||||
citems = counts.items()
|
||||
rare_keys = [k for k, v in citems if v < 10]
|
||||
lack_counts = dict((k, v) for k, v in citems if k.startswith('LACKS '))
|
||||
bad_counts = dict((k, v) for k, v in citems if k.startswith('BAD '))
|
||||
no_counts = dict((k, v) for k, v in citems if k.startswith('NO '))
|
||||
tag_counts = dict((k, v) for k, v in citems if k not in lack_counts and
|
||||
k not in bad_counts and k not in no_counts and k != 'MISSING KEYS')
|
||||
|
||||
# flag whether the tag is needed, ok, or not
|
||||
tag_quality = dict((k, '*') for k in REQUIRED_TAGS)
|
||||
tag_quality.update((k, '+') for k in OPTIONAL_TAGS)
|
||||
linfo_counts = dict((k, len(v)) for k, v in all_linfo.iteritems())
|
||||
linfo_uniq_counts = dict((k, len(v)) for k, v in unique_linfo.iteritems())
|
||||
|
||||
log('\nFound: %s bundles\n %s unique bundles' % (len(all_bundles), len(unique_bundles)))
|
||||
for d, name, d2 in [(tag_counts, '\nattribute counts:', tag_quality),
|
||||
(lack_counts, '\nmissing required keys:', {}),
|
||||
(no_counts, '\nunused optional keys:', {}),
|
||||
(bad_counts, '\nill-formed values:', {}),
|
||||
(linfo_counts, '\nlinfo counts: total localised', linfo_uniq_counts),
|
||||
(linfo_keys, '\nlinfo keys:', {})]:
|
||||
log(name)
|
||||
counts_reversed = [(v, k) for (k, v) in d.iteritems()]
|
||||
counts_reversed.sort()
|
||||
counts_reversed.reverse()
|
||||
for (k, v) in counts_reversed:
|
||||
log("%-25s %4s %4s" % (v, k, d2.get(v, '')))
|
||||
|
||||
log("\nRare keys:")
|
||||
for k in rare_keys:
|
||||
if k.startswith('BAD '):
|
||||
continue
|
||||
log(k)
|
||||
for b in bundles:
|
||||
v = b.debug().get(k)
|
||||
if v:
|
||||
log(' %-25s %s' % (b.bundle_id, v))
|
||||
|
||||
|
||||
log("\nInteresting contents:")
|
||||
for k, v in bad_contents.iteritems():
|
||||
log(k)
|
||||
for x in v.iteritems():
|
||||
log(' %s: %s' % x)
|
||||
|
||||
log("\nInteresting linfo:")
|
||||
for k in ('pseudo',):
|
||||
log(k)
|
||||
for a in all_linfo[k]:
|
||||
if a in unique_linfo.get(k, []):
|
||||
log(' * %s (%s vs. %s)' % (a.bundle_id, a.name, a.linfo[k]['name']))
|
||||
else:
|
||||
log(' %s (%s)' % (a.bundle_id, a.name))
|
||||
|
||||
log("\nLicenses:")
|
||||
for lic, v in licenses.iteritems():
|
||||
log("%-20s %s" %(repr(lic), len(v)))
|
||||
|
||||
log("\nRare licenses:")
|
||||
for lic, v in licenses.iteritems():
|
||||
if len(v) < 3:
|
||||
log(' %s' % lic)
|
||||
for x in v:
|
||||
log(" %s" %(x))
|
||||
|
||||
|
||||
|
||||
log("\nAlmost valid activities:")
|
||||
for b in bundles:
|
||||
d = b.debug()
|
||||
if d['MISSING KEYS'] == 1:
|
||||
missing = ', '.join(x for x in d if x.startswith('LACKS'))
|
||||
bad_values = ', '. join(x for x in d if x.startswith('BAD'))
|
||||
log("%-20s %s %s" %(b.name, missing, bad_values))
|
||||
|
||||
log("\nValid activities (maybe):")
|
||||
for b in bundles:
|
||||
d = b.debug()
|
||||
bid = b.bundle_id
|
||||
if (d['MISSING KEYS'] == 0 and
|
||||
bid not in bad_contents['BAD mime_types']):
|
||||
log("%-20s - %s" %(b.name, bid))
|
||||
#log(a.raw_data)
|
||||
|
||||
|
||||
|
||||
|
||||
def read_info_file(zipfile, path, section):
|
||||
"""Return a dictionary matching the contents of the config file at
|
||||
path in zipfile"""
|
||||
cp = SafeConfigParser()
|
||||
info = StringIO(zipfile.read(path))
|
||||
cp.readfp(info)
|
||||
return dict(cp.items(section))
|
||||
|
||||
def canonicalise(lang):
|
||||
"""Make all equivalent language strings the same.
|
||||
>>> canonicalise('Zh-cN')
|
||||
zh-CN
|
||||
>>> canonicalise('zh_CN')
|
||||
zh-CN
|
||||
"""
|
||||
lang = lang.replace('_', '-').upper()
|
||||
bits = lang.split('-', 1)
|
||||
bits[0] = bits[0].lower()
|
||||
return '-'.join(bits)
|
||||
|
||||
def locale_search_path(locale):
|
||||
"""Find a series of sensible locales to try, including
|
||||
DEFAULT_LANG. For example 'zh-CN' would become ('zh-CN', 'zh',
|
||||
'DEFAULT_LANG')."""
|
||||
#XXX might be better to be storing locale as tuple
|
||||
if '-' in locale:
|
||||
return (locale, locale.split('-')[0], DEFAULT_LANG)
|
||||
return (locale, DEFAULT_LANG)
|
||||
|
||||
|
||||
|
||||
def read_metadata(bundle_dir):
|
||||
"""Attempt to read data in a metadata file. Raises expected
|
||||
exceptions if the metadata file isn't readable. The file should
|
||||
look something like this:
|
||||
|
||||
[org.laptop.Pippy]
|
||||
description = Succinct description of this activity.
|
||||
|
||||
[org.laptop.Develop]
|
||||
description = Succinct description of this activity.
|
||||
web_icon = develop.png
|
||||
"""
|
||||
md_files = [os.path.join(bundle_dir, x)
|
||||
for x in os.listdir(bundle_dir) if x.endswith('.info')]
|
||||
cp = SafeConfigParser()
|
||||
cp.read(md_files)
|
||||
metadata = {}
|
||||
for section in cp.sections():
|
||||
metadata[section] = dict(x for x in cp.items(section))
|
||||
return metadata
|
||||
|
||||
|
||||
def htmlise_bundles(bundle_dir, dest_html):
|
||||
"""Makes a nice html manifest for the bundles in a directory. The
|
||||
manifest only shows the newest version of each bundle.
|
||||
"""
|
||||
#so, we collect up a dictionary of lists, then sort each list on
|
||||
#the version number to find the newest.
|
||||
|
||||
bundles = [os.path.join(bundle_dir, x)
|
||||
for x in os.listdir(bundle_dir) if x.endswith('.xo') or x.endswith('.xol')]
|
||||
|
||||
try:
|
||||
metadata = read_metadata(bundle_dir)
|
||||
except Exception, e:
|
||||
log("had trouble reading metadata: %s" % e)
|
||||
metadata = {}
|
||||
|
||||
all_bundles = {}
|
||||
for filename in bundles:
|
||||
try:
|
||||
if filename.endswith('.xo'):
|
||||
bundle = Activity(filename)
|
||||
else:
|
||||
bundle = Content(filename)
|
||||
x = all_bundles.setdefault(bundle.bundle_id, [])
|
||||
x.append((bundle.mtime, bundle))
|
||||
except Exception, e:
|
||||
log("Couldn't find good activity/library info in %s (Error: %s)" % (filename, e))
|
||||
|
||||
newest = []
|
||||
# create an index for each language that has a template
|
||||
# but track any locales in bundles in case we do not have templates for them
|
||||
locales = [os.path.join(o) for o in os.listdir(TEMPLATE_DIR) if os.path.isdir(os.path.join(TEMPLATE_DIR,o))]
|
||||
locales_found = set ()
|
||||
for versions in all_bundles.values():
|
||||
versions = [x[1] for x in sorted(versions)]
|
||||
# end of list is the newest; beginning of list might need deleting
|
||||
latest = versions.pop()
|
||||
locales_found.update(latest.linfo)
|
||||
newest.append(latest)
|
||||
goners = versions[:-KEEP_OLD_VERSIONS]
|
||||
keepers = versions[-KEEP_OLD_VERSIONS:]
|
||||
for v in goners:
|
||||
fn = os.path.join(bundle_dir, v.url)
|
||||
os.remove(fn)
|
||||
latest.set_older_versions(keepers)
|
||||
|
||||
if latest.bundle_id in metadata:
|
||||
# we have extra metadata with which to fill out details
|
||||
# presumably this is mainly human-oriented description.
|
||||
d = metadata[latest.bundle_id]
|
||||
for k in ('description', 'name'):
|
||||
if k in d:
|
||||
setattr(latest, k, d[k])
|
||||
|
||||
log('found locales: %s' % locales)
|
||||
|
||||
# assume locales is not empty as we have at least the default language
|
||||
for locale in locales:
|
||||
try:
|
||||
make_html(newest, locale, '%s.%s' % (dest_html, locale))
|
||||
except Exception, e:
|
||||
log("Couldn't make page for %s (Error: %s)" % (locale, e), syslog.LOG_WARNING)
|
||||
|
||||
# make_varfile(locales, dest_html)- have switched to multiviews, so var not needed
|
||||
|
||||
|
||||
def make_varfile(locales, dest_html):
|
||||
f = open(dest_html + '.var', 'w')
|
||||
index = os.path.basename(dest_html)
|
||||
f.write('URI: %s\n\n' % index)
|
||||
for locale in locales:
|
||||
f.write('URI: %s.%s\n' % (index, locale))
|
||||
f.write('Content-type: text/html; charset=utf-8\n')
|
||||
f.write('Content-language: %s\n\n' % locale)
|
||||
# now the default, slightly higher qs
|
||||
f.write('URI: %s.DEFAULT\n' % index)
|
||||
f.write('Content-type: text/html; charset=utf-8\n')
|
||||
f.write('Content-language: en\n\n')
|
||||
|
||||
f.close()
|
||||
|
||||
def read_template(name, locale):
|
||||
"""Try to read the locale's template, falling back to the
|
||||
default."""
|
||||
#also try containing locales, eg 'zh' for 'zh-CN'
|
||||
for x in locale_search_path(locale):
|
||||
try:
|
||||
f = open(os.path.join(TEMPLATE_DIR, x, name))
|
||||
break
|
||||
except (OSError, IOError), e:
|
||||
#log(str(e))
|
||||
continue
|
||||
s = f.read()
|
||||
f.close()
|
||||
return s
|
||||
|
||||
|
||||
def make_html(bundles, locale, filename):
|
||||
"""Write a microformated index for the activities in the appropriate language,
|
||||
and save it to filename."""
|
||||
page_tmpl = read_template('page', locale)
|
||||
act_tmpl = read_template('activity', locale)
|
||||
|
||||
#bundles.sort() won't cut it.
|
||||
schwartzian = [ (x.get_name(locale), x.to_html(locale, act_tmpl)) for x in bundles ]
|
||||
schwartzian.sort()
|
||||
s = page_tmpl % {'activities': '\n'.join(x[1] for x in schwartzian)}
|
||||
|
||||
if os.path.exists(filename):
|
||||
shutil.move(filename, filename + '~')
|
||||
f = open(filename, 'w')
|
||||
f.write(s)
|
||||
f.close()
|
||||
|
||||
|
||||
|
||||
|
||||
|
133
roles/activity-server/tasks/main.yml
Normal file
133
roles/activity-server/tasks/main.yml
Normal file
|
@ -0,0 +1,133 @@
|
|||
# assume apache in admin group
|
||||
|
||||
- name: Create xs-activity-server directory tree
|
||||
file: path={{ item }}
|
||||
mode=0755
|
||||
owner=root
|
||||
group=admin
|
||||
state=directory
|
||||
with_items:
|
||||
- /library/xs-activity-server
|
||||
- /library/xs-activity-server/activities
|
||||
- /library/xs-activity-server/lang_templates
|
||||
- /library/xs-activity-server/www.0
|
||||
- /library/xs-activity-server/tmp
|
||||
|
||||
# Wish synchronize worked, but it doesn't
|
||||
|
||||
- name: Copy language templates
|
||||
command: rsync -a {{xsce_dir}}/roles/activity-server/files/lang_templates /library/xs-activity-server/
|
||||
|
||||
- name: Copy default index files
|
||||
copy: src={{ item }}
|
||||
dest=/library/xs-activity-server/www.0
|
||||
mode=0755
|
||||
owner=root
|
||||
group=root
|
||||
with_fileglob:
|
||||
- www.0/index.html.*
|
||||
|
||||
- name: Point www to www.0 as default
|
||||
file: src=/library/xs-activity-server/www.0
|
||||
dest=/library/xs-activity-server/www
|
||||
owner=root
|
||||
group=admin
|
||||
state=link
|
||||
|
||||
- name: Chown language templates
|
||||
file: path=/library/xs-activity-server/lang_templates
|
||||
mode=0644
|
||||
owner=root
|
||||
group=admin
|
||||
state=directory
|
||||
recurse=yes
|
||||
|
||||
# We should have a var for python site-packages directory
|
||||
|
||||
- name: Create xs-activity-server python site-packages directory
|
||||
file: path=/usr/lib/python2.7/site-packages/xs_activities
|
||||
mode=0755
|
||||
owner=root
|
||||
group=root
|
||||
state=directory
|
||||
|
||||
- name: Install Python module
|
||||
copy: src=xs_activities/__init__.py
|
||||
dest=/usr/lib/python2.7/site-packages/xs_activities
|
||||
mode=0644
|
||||
owner=root
|
||||
group=root
|
||||
|
||||
- name: Copy scripts to /usr/bin
|
||||
copy: src={{ item }}
|
||||
dest=/usr/bin
|
||||
mode=0755
|
||||
owner=root
|
||||
group=root
|
||||
with_items:
|
||||
- bin/xs-regenerate-activities
|
||||
- bin/xs-check-activities
|
||||
|
||||
# Do in ansible what was done in /etc/sysconfig/olpc-scripts/setup.d/xs-activity-server script
|
||||
|
||||
- name: Copy xs-activity-server config file
|
||||
template: src=xs-activity-server.conf
|
||||
dest=/etc/{{ apache_config_dir }}
|
||||
owner=root
|
||||
group=root
|
||||
mode=0644
|
||||
|
||||
- name: enable mod_expires for debian
|
||||
command: a2enmod expires
|
||||
when: is_debian
|
||||
|
||||
- name: create the link which enables the site
|
||||
file: src=/etc/apache2/sites-available/xs-activity-server.conf
|
||||
dest=/etc/apache2/sites-enabled/xs-activity-server.conf
|
||||
state=link
|
||||
when: activity_server_enabled and is_debian
|
||||
|
||||
- name: delete the link which enables the site
|
||||
file: src=/etc/apache2/sites-available/xs-activity-server.conf
|
||||
dest=/etc/apache2/sites-enabled/xs-activity-server.conf
|
||||
state=absent
|
||||
when: not activity_server_enabled and is_debian
|
||||
|
||||
|
||||
- name: Copy xs-activity-server usbmount file
|
||||
template: src=usbmount-60-xs-activity-server-installcontent
|
||||
dest=/etc/usbmount/mount.d
|
||||
owner=root
|
||||
group=root
|
||||
mode=0755
|
||||
|
||||
# TODO: Fix multiview so it supports portal language menu
|
||||
# For it only supports client's language code
|
||||
|
||||
# TODO: Upload Activity via web interface
|
||||
# and figure out what to do with olpc_activities.service
|
||||
|
||||
# short term addition of link for upload-activity server
|
||||
# ln -sf /usr/share/xs-config/cfg/html/top/en/cntr_upl_activity.php {{ doc_root }}/upload_activity.php
|
||||
|
||||
|
||||
- name: Restart httpd
|
||||
service: name={{ apache_service }}
|
||||
enabled=yes
|
||||
state=restarted
|
||||
|
||||
- name: add xs-activity-server to service list
|
||||
ini_file: dest='{{ service_filelist }}'
|
||||
section=activity-server
|
||||
option='{{ item.option }}'
|
||||
value='{{ item.value }}'
|
||||
with_items:
|
||||
- option: name
|
||||
value: "Activity Server"
|
||||
- option: description
|
||||
value: "Download an Activity."
|
||||
- option: path
|
||||
value: /activities
|
||||
- option: enabled
|
||||
value: "{{ xo_services_enabled }}"
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
#!/bin/bash
|
||||
# Part of the xs-activity-server package
|
||||
#
|
||||
# based on a similarly named script in the xs-rsync package
|
||||
# by Martin Langhoff <martin@laptop.org>
|
||||
#
|
||||
# Adapted for xs-activity-server by Douglas Bagnall
|
||||
# <douglas@paradise.net.nz>
|
||||
#
|
||||
# Copyright: One Laptop per Child
|
||||
|
||||
set -e
|
||||
|
||||
VERBOSE=yes
|
||||
MAGIC_DIR=$UM_MOUNTPOINT/xs-activity-server
|
||||
|
||||
FINAL_DIR=/library/xs-activity-server/activities
|
||||
|
||||
FILES_TO_RM=""
|
||||
|
||||
# combined with set -e, error() is called if something fails.
|
||||
error(){
|
||||
logger -puser.err -t "xs-activity-server[$$]" "Error at line $(caller)"
|
||||
[ "$FILES_TO_RM" ] && rm -rf $FILES_TO_RM
|
||||
}
|
||||
trap error ERR
|
||||
|
||||
|
||||
# Log a string via the syslog facility.
|
||||
log()
|
||||
{
|
||||
if test $1 != debug || expr "$VERBOSE" : "[yY]" > /dev/null; then
|
||||
logger -p user.$1 -t "xs-activity-server[$$]" -- "$2"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
STEPS=7
|
||||
|
||||
[ -d $MAGIC_DIR ] || exit 0
|
||||
|
||||
log notice 'Found activity install directory';
|
||||
log notice "[1/$STEPS] Checking whether it has a manifest";
|
||||
|
||||
if [ -r $MAGIC_DIR/manifest.sha1 ];then
|
||||
log notice "[2/$STEPS] Seems to have a manifest";
|
||||
else
|
||||
log err "[2/$STEPS] Missing manifest"
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
## Do we have enough space?
|
||||
# note: we could use awk {'print $4'} instead of the
|
||||
# perl regex, but it breaks with long /dev nodes
|
||||
# such as those from LVMs -which wrap. The regex captures the
|
||||
# number just left of the number with the percentage sign.
|
||||
NEED=`du -s -B1M $MAGIC_DIR | awk {'print $1'}`
|
||||
HAVE=`df -B1M $FINAL_DIR | tail -n1 | \
|
||||
perl -pe 'm/(\d+)\s+\d+\%/; $_=($1-1);'`
|
||||
if [ $NEED -gt $HAVE ];then
|
||||
log err 'Not enough free space in /library for these activities - cancelling';
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
### Copy it first - as the media is bound to be slow
|
||||
# - make this atomic by cp'ing to a tmpdir, and mv'ing into place
|
||||
# to be fail-safe
|
||||
# - mv aside manifest.sha1 and its sig
|
||||
# - TODO? we could avoid cp'ing files we already have using
|
||||
# rsync --copy-dest instead of cp
|
||||
#
|
||||
log notice "[3/$STEPS] Copying activities to disk";
|
||||
TMPDEST=`mktemp -d -p /library/xs-activity-server/tmp`
|
||||
|
||||
#make sure the tmp directory goes
|
||||
FILES_TO_RM="$FILES_TO_RM '$TMPDEST'"
|
||||
|
||||
cp --preserve=timestamps $MAGIC_DIR/* $TMPDEST
|
||||
|
||||
# In a tmpdir we own, safe from race conditions
|
||||
# run the checksums...
|
||||
log notice "[4/$STEPS] Checking the manifest";
|
||||
# mv the manifest to a different dir
|
||||
TMPMANIF=`mktemp -d -p /library/xs-activity-server/tmp`
|
||||
|
||||
FILES_TO_RM="$FILES_TO_RM '$TMPMANIF'"
|
||||
|
||||
|
||||
mv $TMPDEST/manifest.sha1 $TMPMANIF/
|
||||
if [ -e $TMPDEST/manifest.sha1.sig ]; then
|
||||
mv $TMPDEST/manifest.sha1.sig $TMPMANIF/
|
||||
fi
|
||||
xs-sum -c $TMPMANIF/manifest.sha1 -d $TMPDEST
|
||||
|
||||
#Let syslog know what we're doing
|
||||
cd $TMPDEST
|
||||
log notice "found $(ls *.xo |wc -l) activities"
|
||||
log debug "found these activities: $(ls *.xo)"
|
||||
cd -
|
||||
|
||||
log notice "[5/$STEPS] Copy the directories into place";
|
||||
#XXX not checking whether this clobbers existing files.
|
||||
mv $TMPDEST/* $FINAL_DIR
|
||||
|
||||
#So, now all the activities are in place, but maybe they're not
|
||||
#newer than what we have. So xs-regenerate-activities has to work that out.
|
||||
|
||||
log notice "[6/$STEPS] Regenerating the list of available activities";
|
||||
|
||||
/usr/bin/xs-regenerate-activities $FINAL_DIR 2>&1 | logger -p user.debug -t "xs-activity-server[$$]"
|
||||
|
||||
log notice "[$STEPS/$STEPS] Finished - XOs can now update activities.";
|
||||
|
||||
|
||||
rm -fr $FILES_TO_RM
|
30
roles/activity-server/templates/xs-activity-server.conf
Normal file
30
roles/activity-server/templates/xs-activity-server.conf
Normal file
|
@ -0,0 +1,30 @@
|
|||
# xs-activity-server
|
||||
#
|
||||
# Copyright: On Laptop per Child
|
||||
# GPL v2
|
||||
# written by Douglas Bagnall <douglas@paradise.net.nz>
|
||||
#
|
||||
# This belongs in the apache conf.d directory.
|
||||
# (probably /etc/httpd/conf.d/)
|
||||
|
||||
Alias /activities /library/xs-activity-server/www
|
||||
<Directory /library/xs-activity-server/www >
|
||||
# Languages are set in 010-xsce.conf
|
||||
|
||||
ExpiresActive On
|
||||
ExpiresDefault now
|
||||
Options +MultiViews
|
||||
Require all granted
|
||||
#NOTE: an index.html.var file is generated, which ought to make
|
||||
# MultiViews redundant (by my reading) but it doesn't seem to
|
||||
# work. Someone could look at that sometime.
|
||||
</Directory>
|
||||
|
||||
#<Directory /activities >
|
||||
# ExpiresActive On
|
||||
# ExpiresDefault now
|
||||
#</Directory>
|
||||
#<Location /activities >
|
||||
# ExpiresActive On
|
||||
# ExpiresDefault now
|
||||
#</Location>
|
5
roles/ajenti/handlers/main.yml
Normal file
5
roles/ajenti/handlers/main.yml
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
- name: restart ajenti service
|
||||
service: name=ajenti
|
||||
enabled=yes
|
||||
state=restarted
|
14
roles/ajenti/tasks/ajenti-wondershaper.yml
Normal file
14
roles/ajenti/tasks/ajenti-wondershaper.yml
Normal file
|
@ -0,0 +1,14 @@
|
|||
- name: download wondershaper ajenti plugin
|
||||
pip: name="{{ xsce_download_url }}"/ajenti-plugin-wondershaper-0.3.tar.gz
|
||||
extra_args="--download {{ pip_packages_dir }}"
|
||||
when: not {{ use_cache }} and not {{ no_network }}
|
||||
tags:
|
||||
- download2
|
||||
|
||||
|
||||
- name: install wondershaper from local download directory
|
||||
pip: name=ajenti-plugin-wondershaper
|
||||
extra_args="--no-index --find-links=file://{{ pip_packages_dir }}"
|
||||
|
||||
# notify:
|
||||
# - restart ajenti service
|
79
roles/ajenti/tasks/main.yml
Normal file
79
roles/ajenti/tasks/main.yml
Normal file
|
@ -0,0 +1,79 @@
|
|||
- name: Install python-pip package
|
||||
package: name=python-pip
|
||||
state=present
|
||||
tags:
|
||||
- download
|
||||
|
||||
- name: Install required libraries
|
||||
package: name={{ item.pkg }}
|
||||
state=present
|
||||
with_items:
|
||||
- pkg: python-imaging
|
||||
- pkg: python-devel
|
||||
- pkg: libxslt-devel
|
||||
- pkg: pyOpenSSL
|
||||
- pkg: python-daemon
|
||||
- pkg: gcc
|
||||
tags:
|
||||
- download
|
||||
|
||||
- name: download ajenti from our repo
|
||||
pip: name="{{ xsce_download_url }}"/ajenti-0.99.34-patched5.tar.gz
|
||||
extra_args="--download {{ pip_packages_dir }}"
|
||||
when: not {{ use_cache }} and not {{ no_network }}
|
||||
tags:
|
||||
- download2
|
||||
|
||||
- name: install ajenti from local download directory
|
||||
pip: name=ajenti
|
||||
extra_args="--no-index --find-links=file://{{ pip_packages_dir }}"
|
||||
|
||||
# notify:
|
||||
# - restart ajenti service
|
||||
|
||||
- name: download python-catcher
|
||||
pip: name=python-catcher version=0.1.3
|
||||
extra_args="--download {{ pip_packages_dir }}"
|
||||
when: not {{ use_cache }} and not {{ no_network }}
|
||||
tags:
|
||||
- download2
|
||||
|
||||
- name: install python-catcher from local download directory
|
||||
pip: name=python-catcher
|
||||
extra_args="--no-index --find-links=file://{{ pip_packages_dir }}/python-catcher"
|
||||
|
||||
- name: change default port
|
||||
lineinfile: backup=yes
|
||||
dest=/etc/ajenti/config.json
|
||||
state=present
|
||||
backrefs=yes
|
||||
regexp='"port":\s*[0-9]{1,5}'
|
||||
line='"port":9990'
|
||||
|
||||
- name: exe permission to ajenti
|
||||
file: path=/etc/rc.d/init.d/ajenti
|
||||
mode=0744
|
||||
state=file
|
||||
|
||||
- include: ajenti-wondershaper.yml
|
||||
when: 'xsce_lan_iface != ""'
|
||||
|
||||
# handler doesn't fire
|
||||
- name: restart ajenti service
|
||||
service: name=ajenti
|
||||
enabled=yes
|
||||
state=restarted
|
||||
when: ajenti_enabled
|
||||
|
||||
- name: Add ajenti to service list
|
||||
ini_file: dest='{{ service_filelist }}'
|
||||
section=ajenti
|
||||
option='{{ item.option }}'
|
||||
value='{{ item.value }}'
|
||||
with_items:
|
||||
- option: name
|
||||
value: ajenti
|
||||
- option: description
|
||||
value: "Ajenti is a client server systems administration tool controlled by a web browser"
|
||||
- option: enabled
|
||||
value: "{{ ajenti_enabled }}"
|
72
roles/authserver/tasks/main.yml
Normal file
72
roles/authserver/tasks/main.yml
Normal file
|
@ -0,0 +1,72 @@
|
|||
- name: check pip is installed
|
||||
package: name=python-pip
|
||||
state=present
|
||||
tags:
|
||||
- download
|
||||
|
||||
- name: download xs-authserver from pypi
|
||||
pip: name=xs-authserver
|
||||
extra_args="--download {{ pip_packages_dir }}"
|
||||
when: not {{ use_cache }} and not {{ no_network }}
|
||||
tags:
|
||||
- download2
|
||||
|
||||
- name: install xs-authserver from pypi
|
||||
pip: name=xs-authserver
|
||||
extra_args="--no-index --find-links=file://{{ pip_packages_dir }}"
|
||||
|
||||
- name: install gunicorn
|
||||
package: name=python-gunicorn
|
||||
state=present
|
||||
tags:
|
||||
- download
|
||||
|
||||
- name: Configure xs-authserver
|
||||
template: backup=yes
|
||||
src={{ item.src }}
|
||||
dest={{ item.dest }}
|
||||
owner=root
|
||||
group=root
|
||||
mode={{ item.mode }}
|
||||
with_items:
|
||||
- src: xs-authserver.env.j2
|
||||
dest: /etc/sysconfig/xs-authserver
|
||||
mode: 0644
|
||||
- src: xs-authserver.service.j2
|
||||
dest: /etc/systemd/system/xs-authserver.service
|
||||
mode: 0644
|
||||
|
||||
- name: create database folder
|
||||
file: state=directory
|
||||
path=/var/lib/xs-authserver/
|
||||
owner=root
|
||||
group=root
|
||||
mode=0644
|
||||
|
||||
- name: init database
|
||||
command: xs-authserverctl initdb
|
||||
ignore_errors: yes
|
||||
environment:
|
||||
XS_AUTHSERVER_DATABASE: /var/lib/xs-authserver/data.db
|
||||
|
||||
- name: Enable xs-authserver service
|
||||
service: name=xs-authserver
|
||||
enabled=yes
|
||||
when: authserver_enabled
|
||||
|
||||
- name: add xs-authserver to service list
|
||||
ini_file: dest='{{ service_filelist }}'
|
||||
section=xs-authserver
|
||||
option='{{ item.option }}'
|
||||
value='{{ item.value }}'
|
||||
with_items:
|
||||
- option: name
|
||||
value: XS-authserver
|
||||
- option: description
|
||||
value: '"xs-authserver implements a seamless web authentication service
|
||||
using XO laptop registration capabilities. It is heavily inspired
|
||||
by the Moodle OLPC-XS authentication plugin"'
|
||||
- option: port
|
||||
value: 5000
|
||||
- option: path
|
||||
value: /
|
2
roles/authserver/templates/xs-authserver.env.j2
Normal file
2
roles/authserver/templates/xs-authserver.env.j2
Normal file
|
@ -0,0 +1,2 @@
|
|||
XS_AUTHSERVER_OLPC_XS_DB='/home/idmgr/identity.db'
|
||||
XS_AUTHSERVER_DATABASE='/var/lib/xs-authserver/data.db'
|
10
roles/authserver/templates/xs-authserver.service.j2
Executable file
10
roles/authserver/templates/xs-authserver.service.j2
Executable file
|
@ -0,0 +1,10 @@
|
|||
[Unit]
|
||||
Description=XS authentication server
|
||||
After={{ apache_service }}.service local-fs.target
|
||||
|
||||
[Service]
|
||||
EnvironmentFile=-/etc/sysconfig/xs-authserver
|
||||
ExecStart=/usr/bin/gunicorn -n xs-authserver xs_authserver:app -b 0.0.0.0:5000
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
3
roles/awstats/defaults/main.yml
Normal file
3
roles/awstats/defaults/main.yml
Normal file
|
@ -0,0 +1,3 @@
|
|||
awstats_install: True
|
||||
awstats_enabled: False
|
||||
awstats_data_dir: /library/awstats/
|
99
roles/awstats/tasks/install.yml
Normal file
99
roles/awstats/tasks/install.yml
Normal file
|
@ -0,0 +1,99 @@
|
|||
- name: Install awstats package
|
||||
package: name={{ item }}
|
||||
state=present
|
||||
with_items:
|
||||
- awstats
|
||||
- pwauth
|
||||
- openssl
|
||||
tags:
|
||||
- download
|
||||
|
||||
- name: Install awstats package
|
||||
package: name={{ item }}
|
||||
state=present
|
||||
with_items:
|
||||
- libapache2-mod-authnz-external
|
||||
- apache2-utils
|
||||
when: is_debian
|
||||
tags:
|
||||
- download
|
||||
|
||||
- name: enable cgi execution
|
||||
command: a2enmod cgi
|
||||
when: is_debian
|
||||
|
||||
- name: Create directory for awstat to use as intermediate summary storage
|
||||
file: path={{ item }}
|
||||
mode=0750
|
||||
owner={{ apache_data }}
|
||||
group={{ apache_data }}
|
||||
state=directory
|
||||
force=true
|
||||
with_items:
|
||||
- "{{ awstats_data_dir }}"
|
||||
- "{{ apache_log_dir }}"
|
||||
|
||||
- name: Install the Apache config for Advanced Web Statistics
|
||||
template: src=apache.conf
|
||||
dest=/etc/{{ apache_config_dir }}/awstats.conf
|
||||
owner=root
|
||||
group=root
|
||||
mode=0644
|
||||
when: awstats_enabled and is_debian
|
||||
|
||||
- name: Install the Apache config for Advanced Web Statistics
|
||||
template: src=apache-awstats.conf
|
||||
dest=/etc/{{ apache_config_dir }}/awstats.conf
|
||||
owner=root
|
||||
group=root
|
||||
mode=0644
|
||||
when: awstats_enabled and not is_debian
|
||||
|
||||
- name: make sure logrotate does not make logs unreadable
|
||||
template: src=logrotate.d.apache2
|
||||
dest=/etc/logrotate.d/apache2
|
||||
when: is_debian
|
||||
|
||||
- name: See if awstats package installed a config file
|
||||
stat: path=/etc/awstats/awstats.conf
|
||||
register: awstats
|
||||
|
||||
- debug: var=awstats
|
||||
|
||||
- name: If there was a config file installed by package, move it aside
|
||||
command: mv /etc/awstats/awstats.conf /etc/awstats/awstats.conf.dist
|
||||
when: awstats.stat.islnk is defined and not awstats.stat.islnk
|
||||
|
||||
- name: Enable Awstats
|
||||
file: src=/etc/apache2/sites-available/awstats.conf
|
||||
path=/etc/apache2/sites-enabled/awstats.conf
|
||||
state=link
|
||||
when: awstats_enabled and is_debian
|
||||
|
||||
- name: Disable Awstats
|
||||
file: path=/etc/apache2/sites-enabled/awstats.conf
|
||||
state=absent
|
||||
when: not awstats_enabled and is_debian
|
||||
|
||||
- name: Install the awstats config for Advanced Web Statistics
|
||||
template: src=awstats.schoolserver.conf.j2
|
||||
dest=/etc/awstats/awstats.schoolserver.conf
|
||||
owner=root
|
||||
group=root
|
||||
mode=0644
|
||||
when: awstats_enabled
|
||||
|
||||
- name: Create a symbolic link to use when access is by ip address
|
||||
file: src=/etc/awstats/awstats.schoolserver.conf
|
||||
dest=/etc/awstats/awstats.conf
|
||||
state=link
|
||||
when: awstats_enabled
|
||||
|
||||
- name: On first enabling of awstats, summarize httpd logs up to now
|
||||
shell: /bin/perl /usr/share/awstats/wwwroot/cgi-bin/awstats.pl -config=schoolserver -update
|
||||
when: awstats_enabled and not is_debian
|
||||
|
||||
- name: On first enabling of awstats, summarize httpd logs up to now
|
||||
shell: /usr/bin/perl /usr/lib/cgi-bin/awstats.pl -config=schoolserver -update
|
||||
when: awstats_enabled and is_debian
|
||||
|
17
roles/awstats/tasks/main.yml
Normal file
17
roles/awstats/tasks/main.yml
Normal file
|
@ -0,0 +1,17 @@
|
|||
- include: install.yml
|
||||
when: awstats_install
|
||||
|
||||
- name: Add awstats to service list
|
||||
ini_file: dest='{{ service_filelist }}'
|
||||
section=awstats
|
||||
option='{{ item.option }}'
|
||||
value='{{ item.value }}'
|
||||
with_items:
|
||||
- option: name
|
||||
value: awstats
|
||||
- option: description
|
||||
value: '"Awstats is Advanced Web Statistics package written in perl which generates static or dynamic html summaries based upon web server logs"'
|
||||
- option: installed
|
||||
value: "{{ awstats_install }}"
|
||||
- option: enabled
|
||||
value: "{{ awstats_enabled }}"
|
39
roles/awstats/templates/apache-awstats.conf
Normal file
39
roles/awstats/templates/apache-awstats.conf
Normal file
|
@ -0,0 +1,39 @@
|
|||
#
|
||||
# Content of this file, with correct values, can be automatically added to
|
||||
# your Apache server by using the AWStats configure.pl tool.
|
||||
#
|
||||
|
||||
|
||||
# If using Windows and Perl ActiveStat, this is to enable Perl script as CGI.
|
||||
#ScriptInterpreterSource registry
|
||||
|
||||
|
||||
#
|
||||
# Directives to add to your Apache conf file to allow use of AWStats as a CGI.
|
||||
# Note that path "/usr/share/awstats/" must reflect your AWStats install path.
|
||||
#
|
||||
Alias /awstatsclasses "/usr/share/awstats/wwwroot/classes/"
|
||||
Alias /awstatscss "/usr/share/awstats/wwwroot/css/"
|
||||
Alias /awstatsicons "/usr/share/awstats/wwwroot/icon/"
|
||||
ScriptAlias /awstats/ "/usr/share/awstats/wwwroot/cgi-bin/"
|
||||
ScriptAlias /awstats "/usr/share/awstats/wwwroot/"
|
||||
|
||||
|
||||
#
|
||||
# This is to permit URL access to scripts/files in AWStats directory.
|
||||
#
|
||||
<Directory "/usr/share/awstats/wwwroot">
|
||||
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
|
||||
AllowOverride None
|
||||
DirectoryIndex awstats.pl
|
||||
AuthType Basic
|
||||
AuthName "Admin Console"
|
||||
AuthBasicProvider external
|
||||
AuthExternal pwauth
|
||||
require valid-user
|
||||
</Directory>
|
||||
# Additional Perl modules
|
||||
<IfModule mod_env.c>
|
||||
SetEnv PERL5LIB /usr/share/awstats/lib:/usr/share/awstats/plugins
|
||||
</IfModule>
|
||||
|
47
roles/awstats/templates/apache.conf
Normal file
47
roles/awstats/templates/apache.conf
Normal file
|
@ -0,0 +1,47 @@
|
|||
# This provides worldwide access to everything below the directory
|
||||
# Security concerns:
|
||||
# * Raw log processing data is accessible too for everyone
|
||||
# * The directory is by default writable by the httpd daemon, so if
|
||||
# any PHP, CGI or other script can be tricked into copying or
|
||||
# symlinking stuff here, you have a looking glass into your server,
|
||||
# and if stuff can be uploaded to here, you have a public warez site!
|
||||
ScriptAlias /awstats /usr/lib/cgi-bin
|
||||
<Directory /usr/share/awstats>
|
||||
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
|
||||
AllowOverride None
|
||||
DirectoryIndex /cgi-bin/awstats.pl
|
||||
require all granted
|
||||
</Directory>
|
||||
|
||||
# This provides worldwide access to everything below the directory
|
||||
# Security concerns: none known
|
||||
<Directory /usr/share/awstats/icon>
|
||||
Options None
|
||||
AllowOverride None
|
||||
require all granted
|
||||
</Directory>
|
||||
|
||||
# This provides worldwide access to everything below the directory
|
||||
# Security concerns: none known
|
||||
<Directory /usr/share/java/awstats>
|
||||
Options FollowSymLinks
|
||||
AllowOverride None
|
||||
require all granted
|
||||
</Directory>
|
||||
|
||||
# This provides worldwide access to everything in the directory
|
||||
# Security concerns: none known
|
||||
Alias /awstats-icon/ /usr/share/awstats/icon/
|
||||
|
||||
# This provides worldwide access to everything in the directory
|
||||
# Security concerns: none known
|
||||
Alias /awstatsclasses/ /usr/share/java/awstats/
|
||||
|
||||
# This (hopefully) enables _all_ CGI scripts in the default directory
|
||||
# Security concerns: Are you sure _all_ CGI scripts are safe?
|
||||
ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
|
||||
<Directory /usr/lib/cgi-bin>
|
||||
Options +ExecCGI
|
||||
SetHandler cgi-script
|
||||
require all granted
|
||||
</Directory>
|
1561
roles/awstats/templates/awstats.schoolserver.conf.j2
Normal file
1561
roles/awstats/templates/awstats.schoolserver.conf.j2
Normal file
File diff suppressed because it is too large
Load diff
6
roles/awstats/templates/cron.d.awstats
Normal file
6
roles/awstats/templates/cron.d.awstats
Normal file
|
@ -0,0 +1,6 @@
|
|||
MAILTO=root
|
||||
|
||||
*/10 * * * * www-data [ -x /usr/share/awstats/tools/update.sh ] && /usr/share/awstats/tools/update.sh
|
||||
|
||||
# Generate static reports:
|
||||
10 03 * * * www-data [ -x /usr/share/awstats/tools/buildstatic.sh ] && /usr/share/awstats/tools/buildstatic.sh
|
20
roles/awstats/templates/logrotate.d.apache2
Normal file
20
roles/awstats/templates/logrotate.d.apache2
Normal file
|
@ -0,0 +1,20 @@
|
|||
/var/log/apache2/*.log {
|
||||
daily
|
||||
missingok
|
||||
rotate 14
|
||||
compress
|
||||
delaycompress
|
||||
notifempty
|
||||
create 640 root www-data
|
||||
sharedscripts
|
||||
postrotate
|
||||
if /etc/init.d/apache2 status > /dev/null ; then \
|
||||
/etc/init.d/apache2 reload > /dev/null; \
|
||||
fi;
|
||||
endscript
|
||||
prerotate
|
||||
if [ -d /etc/logrotate.d/httpd-prerotate ]; then \
|
||||
run-parts /etc/logrotate.d/httpd-prerotate; \
|
||||
fi; \
|
||||
endscript
|
||||
}
|
3
roles/calibre/defaults/main.yml
Normal file
3
roles/calibre/defaults/main.yml
Normal file
|
@ -0,0 +1,3 @@
|
|||
calibre_port: 8010
|
||||
calibre_dbpath: "/library/calibre"
|
||||
calibre_src_url: "https://raw.githubusercontent.com/kovidgoyal/calibre/master/setup/linux-installer.py"
|
75
roles/calibre/tasks/main.yml
Normal file
75
roles/calibre/tasks/main.yml
Normal file
|
@ -0,0 +1,75 @@
|
|||
- name: Get calibre setup file
|
||||
# the installer works for intel fedora, and Centos, and deals with dependencies
|
||||
get_url:
|
||||
url="{{ calibre_src_url }}"
|
||||
dest="{{ downloads_dir }}/calibre-installer.py"
|
||||
mode=0755
|
||||
tags:
|
||||
download2
|
||||
when: ansible_distribution == "CentOS"
|
||||
|
||||
- name: Install calibre
|
||||
shell: "{{ downloads_dir }}/calibre-installer.py >> /dev/null"
|
||||
args:
|
||||
creates: /usr/bin/calibre-uninstall
|
||||
tags:
|
||||
download2
|
||||
when: calibre_install and ansible_distribution == 'CentOS'
|
||||
|
||||
- name: Install Caibre rpms
|
||||
# the fedora rpm arm version, though older, takes care of dependencies, and exists
|
||||
package: name={{ item }}
|
||||
state=present
|
||||
with_items:
|
||||
- calibre
|
||||
when: calibre_install and ansible_distribution != 'CentOS'
|
||||
tags: download
|
||||
|
||||
- name: Create calibre service(s) and support scripts
|
||||
template: backup=no
|
||||
src={{ item.src }}
|
||||
dest={{ item.dest }}
|
||||
owner=root
|
||||
group=root
|
||||
mode={{ item.mode }}
|
||||
with_items:
|
||||
- { src: 'calibre-serve.service.j2', dest: '/etc/systemd/system/calibre-serve.service', mode: '0644'}
|
||||
- { src: 'calibre.conf', dest: '/etc/{{ apache_config_dir }}', mode: '0644'}
|
||||
when: calibre_install
|
||||
|
||||
- name: Create the link for sites-enabled
|
||||
file: src=/etc/apache2/sites-available/calibre.conf
|
||||
dest=/etc/apache2/sites-enabled/calibre.conf
|
||||
state=link
|
||||
when: is_debian and calibre_enabled
|
||||
|
||||
- name: Enable Calibre server
|
||||
service: name=calibre-serve
|
||||
enabled=yes
|
||||
state=started
|
||||
#async: 900
|
||||
#poll: 5
|
||||
when: calibre_enabled
|
||||
|
||||
- name: Disable Calibre server
|
||||
service: name=calibre-serve
|
||||
enabled=no
|
||||
state=stopped
|
||||
when: not calibre_enabled
|
||||
|
||||
- name: Add calibre to service list
|
||||
ini_file: dest='{{ service_filelist }}'
|
||||
section=calibre
|
||||
option='{{ item.option }}'
|
||||
value='{{ item.value }}'
|
||||
with_items:
|
||||
- option: description
|
||||
value: '"Calibre epub book server"'
|
||||
- option: url
|
||||
value: "{{ calibre_src_url }}"
|
||||
- option: database
|
||||
value: "{{ calibre_dbpath }}"
|
||||
- option: port
|
||||
value: "{{ calibre_port }}"
|
||||
- option: enabled
|
||||
value: "{{ calibre_enabled }}"
|
15
roles/calibre/templates/calibre-serve.service.j2
Normal file
15
roles/calibre/templates/calibre-serve.service.j2
Normal file
|
@ -0,0 +1,15 @@
|
|||
[Unit]
|
||||
Description=Provides the Calibre Book Server
|
||||
After=syslog.target network.target local-fs.target
|
||||
|
||||
[Service]
|
||||
Type=forking
|
||||
PIDFile=/var/run/calibre.pid
|
||||
{% if is_debian %}
|
||||
ExecStart=/usr/bin/calibre-server --daemonize --pidfile=/var/run/calibre.pid --port={{ calibre_port }} --with-library={{ calibre_dbpath }}
|
||||
{% else %}
|
||||
ExecStart=/bin/calibre-server --daemonize --pidfile=/var/run/calibre.pid --port={{ calibre_port }} --with-library={{ calibre_dbpath }}
|
||||
{% endif %}
|
||||
[Install]
|
||||
TimeoutStartSec=900
|
||||
WantedBy=multi-user.target
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue