Giter Club home page Giter Club logo

puppet-portage's Introduction

Puppet Gentoo Portage Module

Provides Gentoo Portage features for Puppet.

Travis Test status: Build Status

/etc/portage/package.*/*

If target contains a /, then the value of target will used as-is. Otherwise it will be prefixed with the relevant directory for that resource type.

package_use

package_use { 'app-admin/puppet':
  use     => ['flag1', 'flag2'],
  target  => 'puppet-flags',
  version => '>=3.0.1',
  ensure  => present,
}

use can be either a string or an array of strings.

package_keywords

package_keywords { 'app-admin/puppet':
  keywords => ['~x86', '-hppa'],
  target   => 'puppet',
  version  => '>=3.0.1',
  ensure   => present,
}

keywords can be either a string or an array of strings.

package_unmask

package_unmask { 'app-admin/puppet':
  target  => 'puppet',
  version => '>=3.0.1',
  ensure  => present,
}

package_mask

package_mask { 'app-admin/puppet':
  target  => 'tree',
  version => '>=3.0.1',
  ensure  => present,
}

package_env

package_env { 'www-client/firefox':
  env     => 'no-lto',
  target  => 'firefox',
  version => '>=20.0',
  ensure  => present,
}

env can be either a string or an array of strings.

make.conf

The default location of make.conf is /etc/portage/make.conf If you want to change it, you should do the following:

class { 'portage':
  make_conf = '/etc/make.conf',
}

In order to add entries to make.conf:

portage::makeconf { 'portdir_overlay':
  content => '/var/lib/layman',
  ensure  => present,
}
portage::makeconf { 'use':
  content => ['flag1', 'flag2'],
  ensure  => present,
}

Changes in make.conf will also trigger re-emerge of the affected packages. You can disable this behaviour by setting make_conf_remerge to false.

You can also specify special content:

portage::makeconf { 'source /var/lib/layman/make.conf': }

portage::package

This module provides a wrapper to the native package type:

portage::package { 'app-admin/puppet':
  use              => ['-minimal', 'augeas'],
  use_version      => '>=3.0.1',
  keywords         => ['~amd64', '~x86'],
  keywords_version => '>=3.0.1',
  mask_version     => '<=2.3.17',
  unmask_version   => '>=3.0.1',
  target           => 'puppet',
  keywords_target  => 'puppet-keywords',
  ensure           => '3.0.1',
  emerge_command   => '/usr/bin/emerge',
}

If no {keywords,use,mask,unmask}\_target is specified, then the value of target is being used. The variables keywords, mask and unmask also accept the special value all, that will create versionless entries. (This applies only to portage::package, if you want versionless entries in any of the above package\_\* types, you can just omit the version attribute.) Any change in portage::package will also trigger the appropriate re-emerge to the affected package.

emerge_command allows special behavior for install & rebuild. The package atom will be appended automatically. This allows installing packages with --oneshot, and/or other emerge arguments.

facts

All make.conf variables and most of the eselect modules are shown by facter

eselect

The eselect type/provider checks for the current state of an eselect module (or gcc-config) by reading the currently selected value.

eselect { 'ruby':
  set => 'ruby19',
}

Some eselect modules have special options or submodules:

eselect { 'python::python2':
  set => 'python2.7',
}

eselect { 'php::apache2':
  set => 'php5.3',
}

webapp

The webapp type/provider can be used to manage webapps via webapp-config.

webapp { 'www.example.org::/app':
  appname    => 'django',
  appversion => '1.4.5',
  server     => 'nginx',
  user       => 'nginx',
  group      => 'nginx',
  secure     => 'yes',
}

layman

The layman type/provider can be used to manage overlays via layman.

layman { 'x11':
  ensure => present,
}

Custom overlay list can be used via overlay_list parameter.

layman { 'custom-overlay':
  ensure => present,
  overlay_list => 'https://some.xml.file.somethere',
}

Installation of Gentoo tools

This module can also handle the installation of various Gentoo tools.

class { 'portage':
  portage_ensure => '2.2.6',
  eix_ensure     => '0.29.4',
  eix_keywords   => ['~amd64', '~x86'],
}

See manifests/init.pp for all the available tools that can be defined. (It is recommended to use hiera in order to define the values)

See Also

Contributors

puppet-portage's People

Contributors

adrienthebo avatar artem-sidorenko avatar david22swan avatar davispuh avatar ghoneycutt avatar johnzimm avatar ramereth avatar robbat2 avatar samuraiii avatar tampakrap avatar thias avatar vikraman avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

puppet-portage's Issues

Specify version in package_*

In package_* there is ability to provide the package in the following forms:

  • app-admin/puppet
  • =app-admin/puppet-3.0.1
  • >app-admin/puppet-3.0.1
  • <app-admin/puppet-3.0.1
  • >=app-admin/puppet-3.0.1
  • <=app-admin/puppet-3.0.1
  • ~app-admin/puppet-3.0.1

It is now possible to provide the full format of the package ($handler$name-$version) instead of $name in package_* but I'd like to extend it a bit and create a new $version attribute for the version, something like:

package_use { "app-admin/puppet":
  use => 'rrdtool',
  version => '>3.0.1',
}

The provider will check if the first char is one of = < > ~ (if it is one of < > then it should check if the second char is =) and then construct the full package name based on $name and $version. In case there is no handler specified, then = is assumed.

The above will allow me to implement separate $*_version variables in portage::package and ultimately do the following:

portage::package { 'app-admin/puppet':
  target => 'puppet',
  use => 'rrdtool',
  mask => '2.7.18',
  unmask => '~3.0.1',
  keywords => '~amd64',
  ensure => 'latest',
}

renaming target leaves an empty file behind

when renaming the target, it leaves behind an empty file:

package_use { "app-misc/foo":
  use_flags = "flag1",
  target = "target1",
}

if I change $target to target2, target1 is still there, containing only the puppet HEADER lines. Imho it should be deleted completely

Support globbing in portage package version specification.

Atoms can include * in the version section to specify a range of packages to mask.

Given an atom like =sys-apps/portage-2.2*

It would match the following:

  • =sys-apps/portage-2.2.234
  • =sys-apps/portage-2.29
  • =sys-apps/portage-2.2_alpha1

The splat operator should be considered part of the version.

[SOLVED] Could not autoload /etc/puppet/modules/portage/lib/puppet/type/package_keywords.rb: cannot load such file -- puppet/util/portage

Trying to get started with Puppet, but want to be sure Gentoo package.* are handled before embarking too far.

Fresh install of Gentoo and Puppet. Once the module is installed Puppet will complete no commands, returning:
Could not run: Could not autoload /etc/puppet/modules/portage/lib/puppet/type/package_keywords.rb: cannot load such file -- puppet/util/portage

I've tried having portage.* as directories and files, revdep-rebuild, etc.

There was a closed issue on a very similar issue, but the solution the guy used still eludes me.

'hopefully the info below will be of use and it's a simple config error on my part. The Ruby warnings could be significant but again are beyond my ken.

leg ~ # emerge --info
Portage 2.1.11.55 (default/linux/amd64/13.0/desktop, gcc-4.6.3, glibc-2.15-r3, 3.7.10-gentoo x86_64)
=================================================================
System uname: Linux-3.7.10-gentoo-x86_64-Intel-R-_Core-TM-2_Duo_CPU_E8400_@_3.00GHz-with-gentoo-2.1
KiB Mem:     1018432 total,    834080 free
KiB Swap:     785404 total,    785404 free
Timestamp of tree: Thu, 11 Apr 2013 23:15:01 +0000
ld GNU ld (GNU Binutils) 2.22
app-shells/bash:          4.2_p37
dev-lang/python:          2.7.3-r3, 3.2.3-r2
dev-util/cmake:           2.8.9
dev-util/pkgconfig:       0.28
sys-apps/baselayout:      2.1-r1
sys-apps/openrc:          0.11.8
sys-apps/sandbox:         2.5
sys-devel/autoconf:       2.69
sys-devel/automake:       1.10.3, 1.11.6, 1.12.6
sys-devel/binutils:       2.22-r1
sys-devel/gcc:            4.6.3
sys-devel/gcc-config:     1.7.3
sys-devel/libtool:        2.4-r1
sys-devel/make:           3.82-r4
sys-kernel/linux-headers: 3.7 (virtual/os-headers)
sys-libs/glibc:           2.15-r3
Repositories: gentoo
ACCEPT_KEYWORDS="amd64"
ACCEPT_LICENSE="* -@EULA"
CBUILD="x86_64-pc-linux-gnu"
CFLAGS="-O2 -march=core2 -pipe -fomit-frame-pointer"
CHOST="x86_64-pc-linux-gnu"
CONFIG_PROTECT="/etc"
CONFIG_PROTECT_MASK="/etc/ca-certificates.conf /etc/env.d /etc/fonts/fonts.conf /etc/gconf /etc/gentoo-release /etc/revdep-rebuild /etc/sandbox.d /etc/terminfo"
CXXFLAGS="-O2 -march=core2 -pipe -fomit-frame-pointer"
DISTDIR="/usr/portage/distfiles"
FCFLAGS="-O2 -pipe"
FEATURES="assume-digests binpkg-logs config-protect-if-modified distlocks ebuild-locks fixlafiles getbinpkg merge-sync news parallel-fetch protect-owned sandbox sfperms strict unknown-features-warn unmerge-logs unmerge-orphans userfetch"
FFLAGS="-O2 -pipe"
GENTOO_MIRRORS="rsync://spleen.jrcpoole.com/gentoo-distfiles rsync://mirror.bytemark.co.uk/gentoo/ http://mirror.qubenet.net/mirror/gentoo/ http://www.mirrorservice.org/sites/www.ibiblio.org/gentoo/ ftp://ftp.mirrorservice.org/sites/www.ibiblio.org/gentoo/"
LANG="en_GB.UTF-8"
LDFLAGS="-Wl,-O1 -Wl,--as-needed"
MAKEOPTS="-j2"
PKGDIR="/usr/portage/packages"
PORTAGE_CONFIGROOT="/"
PORTAGE_RSYNC_OPTS="--recursive --links --safe-links --perms --times --compress --force --whole-file --delete --stats --human-readable --timeout=180 --exclude=/distfiles --exclude=/local --exclude=/packages"
PORTAGE_TMPDIR="/var/tmp"
PORTDIR="/usr/portage"
PORTDIR_OVERLAY=""
SYNC="rsync://spleen.jrcpoole.com/gentoo-portage"
USE="X a52 aac acl acpi alsa amd64 berkdb bindist bluetooth branding bzip2 cairo cdda cdr cli consolekit cracklib crypt cups cxx dbus dri dts dvd dvdr emboss encode exif fam firefox flac fortran gif gpm iconv jpeg kerberos lcms ldap libnotify mad mmext mmx mng modules mp3 mp4 mpeg mudflap multilib ncurses nls nptl ogg opengl openmp pam pango pcre pdf png policykit ppds qt3support qt4 readline sdl session spell sse sse2 ssl startup-notification svg threads tiff truetype udev udisks unicode upower usb vorbis wxwidgets x264 xcb xml xv xvid zlib" ABI_X86="64" ALSA_CARDS="ali5451 als4000 atiixp atiixp-modem bt87x ca0106 cmipci emu10k1x ens1370 ens1371 es1938 es1968 fm801 hda-intel intel8x0 intel8x0m maestro3 trident usb-audio via82xx via82xx-modem ymfpci" ALSA_PCM_PLUGINS="adpcm alaw asym copy dmix dshare dsnoop empty extplug file hooks iec958 ioplug ladspa lfloat linear meter mmap_emul mulaw multi null plug rate route share shm softvol" APACHE2_MODULES="authn_core authz_core socache_shmcb unixd actions alias auth_basic authn_alias authn_anon authn_dbm authn_default authn_file authz_dbm authz_default authz_groupfile authz_host authz_owner authz_user autoindex cache cgi cgid dav dav_fs dav_lock deflate dir disk_cache env expires ext_filter file_cache filter headers include info log_config logio mem_cache mime mime_magic negotiation rewrite setenvif speling status unique_id userdir usertrack vhost_alias" CALLIGRA_FEATURES="kexi words flow plan sheets stage tables krita karbon braindump" CAMERAS="ptp2" COLLECTD_PLUGINS="df interface irq load memory rrdtool swap syslog" ELIBC="glibc" GPSD_PROTOCOLS="ashtech aivdm earthmate evermore fv18 garmin garmintxt gpsclock itrax mtk3301 nmea ntrip navcom oceanserver oldstyle oncore rtcm104v2 rtcm104v3 sirf superstar2 timing tsip tripmate tnt ubx" GRUB_PLATFORMS="pc" INPUT_DEVICES="evdev" KERNEL="linux" LCD_DEVICES="bayrad cfontz cfontz633 glk hd44780 lb216 lcdm001 mtxorb ncurses text" LIBREOFFICE_EXTENSIONS="presenter-console presenter-minimizer" LINGUAS="en" OFFICE_IMPLEMENTATION="libreoffice" PHP_TARGETS="php5-3" PYTHON_SINGLE_TARGET="python2_7" PYTHON_TARGETS="python2_7 python3_2" RUBY_TARGETS="ruby18 ruby19" USERLAND="GNU" VIDEO_CARDS="virtualbox" XTABLES_ADDONS="quota2 psd pknock lscan length2 ipv4options ipset ipp2p iface geoip fuzzy condition tee tarpit sysrq steal rawnat logmark ipmark dhcpmac delude chaos account"
Unset:  CPPFLAGS, CTARGET, EMERGE_DEFAULT_OPTS, INSTALL_MASK, LC_ALL, PORTAGE_BUNZIP2_COMMAND, PORTAGE_COMPRESS, PORTAGE_COMPRESS_FLAGS, PORTAGE_RSYNC_EXTRA_OPTS, USE_PYTHON

leg ~ # emerge -va puppet
receiving incremental file list
Packages
      795636 100%   10.69MB/s    0:00:00 (xfer#1, to-check=0/1)

sent 56 bytes  received 795835 bytes  530594.00 bytes/sec
total size is 795636  speedup is 1.00

These are the packages that would be merged, in order:

Calculating dependencies... done!
[ebuild   R    ] sys-apps/net-tools-1.60_p20120127084908  USE="nls old-output* -static" 223 kB
[ebuild  N     ] virtual/ruby-ssl-0:ruby18  RUBY_TARGETS="(ruby18)" 0 kB
[ebuild  N     ] virtual/ruby-ssl-1:ruby19  RUBY_TARGETS="(ruby19)" 0 kB
[ebuild  N     ] dev-ruby/facter-1.6.16  USE="dmi {-test}" RUBY_TARGETS="ruby18 ruby19 -jruby (-ree18)" 136 kB
[ebuild  N     ] app-admin/puppet-2.7.21  USE="ldap -augeas -diff -doc -emacs -minimal -rrdtool (-selinux) -shadow -sqlite3 {-test} -vim-syntax -xemacs" RUBY_TARGETS="ruby18 ruby19" 1,984 kB                                                                                                                                                                        

Total: 5 packages (4 new, 1 reinstall), Size of downloads: 2,343 kB

Would you like to merge these packages? [Yes/No] y

<< snip >>

leg ~ # shutdown -r -y now



leg ~ # puppet describe -s package
/usr/lib64/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require': iconv will be deprecated in the future, use String#encode instead.
racc/parser.rb:27: warning: already initialized constant Racc_Runtime_Version
racc/parser.rb:28: warning: already initialized constant Racc_Runtime_Revision
racc/parser.rb:30: warning: already initialized constant Racc_Runtime_Core_Version_R
racc/parser.rb:31: warning: already initialized constant Racc_Runtime_Core_Revision_R
racc/parser.rb:35: warning: already initialized constant Racc_Runtime_Core_Revision_C
racc/parser.rb:39: warning: already initialized constant Racc_Main_Parsing_Routine
racc/parser.rb:40: warning: already initialized constant Racc_YY_Parse_Method
racc/parser.rb:41: warning: already initialized constant Racc_Runtime_Core_Version
racc/parser.rb:42: warning: already initialized constant Racc_Runtime_Core_Revision
racc/parser.rb:43: warning: already initialized constant Racc_Runtime_Type
/usr/lib64/ruby/site_ruby/1.9.1/puppet/provider/service/freebsd.rb:8: warning: class variable access from toplevel
/usr/lib64/ruby/site_ruby/1.9.1/puppet/provider/service/freebsd.rb:9: warning: class variable access from toplevel
/usr/lib64/ruby/site_ruby/1.9.1/puppet/provider/service/freebsd.rb:10: warning: class variable access from toplevel
/usr/lib64/ruby/site_ruby/1.9.1/puppet/provider/service/bsd.rb:12: warning: class variable access from toplevel
/usr/lib64/ruby/site_ruby/1.9.1/puppet/type/tidy.rb:104: warning: class variable access from toplevel
/usr/lib64/ruby/site_ruby/1.9.1/puppet/type/tidy.rb:109: warning: class variable access from toplevel
/usr/lib64/ruby/site_ruby/1.9.1/puppet/type/tidy.rb:109: warning: class variable access from toplevel
/usr/lib64/ruby/site_ruby/1.9.1/puppet/type/tidy.rb:110: warning: class variable access from toplevel
/usr/lib64/ruby/site_ruby/1.9.1/puppet/type/tidy.rb:110: warning: class variable access from toplevel
/usr/lib64/ruby/site_ruby/1.9.1/puppet/type/tidy.rb:111: warning: class variable access from toplevel
/usr/lib64/ruby/site_ruby/1.9.1/puppet/type/tidy.rb:111: warning: class variable access from toplevel
/usr/lib64/ruby/site_ruby/1.9.1/puppet/type/tidy.rb:151: warning: class variable access from toplevel

package
=======
Manage packages.  There is a basic dichotomy in package
support right now:  Some package types (e.g., yum and apt) can
retrieve their own package files, while others (e.g., rpm and sun)
cannot.  For those package formats that cannot retrieve their own files,
you can use the `source` parameter to point to the correct file.

Puppet will automatically guess the packaging format that you are
using based on the platform you are on, but you can override it
using the `provider` parameter; each provider defines what it
requires in order to function, and you must meet those requirements
to use a given provider.

**Autorequires:** If Puppet is managing the files specified as a
package's `adminfile`, `responsefile`, or `source`, the package
resource will autorequire those files.


Parameters
----------
    adminfile, allowcdrom, category, configfiles, description, ensure,
    flavor, install_options, instance, name, platform, responsefile, root,
    source, status, type, vendor

Providers
---------
    aix, appdmg, apple, apt, aptitude, aptrpm, blastwave, dpkg, fink,
    freebsd, gem, hpux, macports, msi, nim, openbsd, pacman, pip, pkg,
    pkgdmg, pkgutil, portage, ports, portupgrade, rpm, rug, sun,
    sunfreeware, up2date, urpmi, yum, zypper
leg ~ # 




leg ~ # puppet module install adrien/portage
/usr/lib64/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require': iconv will be deprecated in the future, use String#encode instead.
Preparing to install into /etc/puppet/modules ...
Downloading from http://forge.puppetlabs.com ...
Installing -- do not interrupt ...
/etc/puppet/modules
└─┬ adrien-portage (v2.0.1)
  └── ripienaar-concat (v0.2.0)
  
leg ~ # puppet describe package
/usr/lib64/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require': iconv will be deprecated in the future, use String#encode instead.
Could not run: Could not autoload /etc/puppet/modules/portage/lib/puppet/type/package_keywords.rb: cannot load such file -- puppet/util/portage
leg ~

leg ~ # puppet describe file
/usr/lib64/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require': iconv will be deprecated in the future, use String#encode instead.
Could not run: Could not autoload /etc/puppet/modules/portage/lib/puppet/type/package_keywords.rb: cannot load such file -- puppet/util/portage
leg ~ # 


leg ~ # ls -R /etc/puppet/
/etc/puppet/:
auth.conf  fileserver.conf  manifests  modules  puppet.conf

/etc/puppet/manifests:

/etc/puppet/modules:
concat  portage

/etc/puppet/modules/concat:
CHANGELOG  LICENSE  Modulefile  README.markdown  Rakefile  files  lib  manifests  metadata.json  spec

/etc/puppet/modules/concat/files:
concatfragments.sh  null

/etc/puppet/modules/concat/files/null:

/etc/puppet/modules/concat/lib:
facter

/etc/puppet/modules/concat/lib/facter:
concat_basedir.rb

/etc/puppet/modules/concat/manifests:
fragment.pp  init.pp  setup.pp

/etc/puppet/modules/concat/spec:
defines  fixtures  spec_helper.rb

/etc/puppet/modules/concat/spec/defines:
init_spec.rb

/etc/puppet/modules/concat/spec/fixtures:
manifests

/etc/puppet/modules/concat/spec/fixtures/manifests:
site.pp

/etc/puppet/modules/portage:
CHANGELOG  Gemfile  Gemfile.lock  LICENSE  Modulefile  README.markdown  Vagrantfile  lib  manifests  metadata.json  spec  templates

/etc/puppet/modules/portage/lib:
facter  puppet

/etc/puppet/modules/portage/lib/facter:
eselect.rb  portage.rb  util

/etc/puppet/modules/portage/lib/facter/util:
portage.rb

/etc/puppet/modules/portage/lib/puppet:
provider  type  util

/etc/puppet/modules/portage/lib/puppet/provider:
eselect  package_keywords  package_mask  package_unmask  package_use  portagefile.rb

/etc/puppet/modules/portage/lib/puppet/provider/eselect:
eselect.rb

/etc/puppet/modules/portage/lib/puppet/provider/package_keywords:
parsed.rb

/etc/puppet/modules/portage/lib/puppet/provider/package_mask:
parsed.rb

/etc/puppet/modules/portage/lib/puppet/provider/package_unmask:
parsed.rb

/etc/puppet/modules/portage/lib/puppet/provider/package_use:
parsed.rb

/etc/puppet/modules/portage/lib/puppet/type:
eselect.rb  package_keywords.rb  package_mask.rb  package_unmask.rb  package_use.rb

/etc/puppet/modules/portage/lib/puppet/util:
portage.rb

/etc/puppet/modules/portage/manifests:
init.pp  makeconf.pp  package.pp  params.pp  postsync.pp

/etc/puppet/modules/portage/spec:
integration  lib  spec_helper.rb  support  unit

/etc/puppet/modules/portage/spec/integration:
provider

/etc/puppet/modules/portage/spec/integration/provider:
package_keywords  package_mask  package_unmask  package_use

/etc/puppet/modules/portage/spec/integration/provider/package_keywords:
parsed_spec.rb

/etc/puppet/modules/portage/spec/integration/provider/package_mask:
parsed_spec.rb

/etc/puppet/modules/portage/spec/integration/provider/package_unmask:
parsed_spec.rb

/etc/puppet/modules/portage/spec/integration/provider/package_use:
parsed_spec.rb

/etc/puppet/modules/portage/spec/lib:
puppet_integration  puppet_integration.rb

/etc/puppet/modules/portage/spec/lib/puppet_integration:
files.rb  fixtures.rb  tmpdir_manager.rb

/etc/puppet/modules/portage/spec/support:
integration

/etc/puppet/modules/portage/spec/support/integration:
provider

/etc/puppet/modules/portage/spec/support/integration/provider:
shared_contexts.rb  shared_examples.rb

/etc/puppet/modules/portage/spec/unit:
provider  type  util

/etc/puppet/modules/portage/spec/unit/provider:
package_keywords  package_mask  package_unmask  package_use

/etc/puppet/modules/portage/spec/unit/provider/package_keywords:
parsed_spec.rb

/etc/puppet/modules/portage/spec/unit/provider/package_mask:
parsed_spec.rb

/etc/puppet/modules/portage/spec/unit/provider/package_unmask:
parsed_spec.rb

/etc/puppet/modules/portage/spec/unit/provider/package_use:
parsed_spec.rb

/etc/puppet/modules/portage/spec/unit/type:
package_keywords_spec.rb  package_mask_spec.rb  package_unmask_spec.rb  package_use_spec.rb

/etc/puppet/modules/portage/spec/unit/util:
portage_spec.rb

/etc/puppet/modules/portage/templates:
makeconf.conf.erb  makeconf.header.conf.erb  postsync.sh.erb
leg ~ # 
 

package.pp emerges package twice

when the package is not installed at all, and a portage::package specifies useflags different than the default ones, then the package gets emerged twice, probably because of the following:

  1. emerge $package
  2. package.use/$target gets created
  3. emerge --reinstall=changed-use $package
    The fix is to create the package.* targets before emerging the package. Needs investigation though to make sure that this is the actual issue

Could not autoload puppet/type/package_keywords:

I had a problem when I was trying to use keywords in portage::package like this:

    portage::package {'dev-php/pecl-sphinx':
        ensure   => present,
        keywords => ['~amd64', '~x86'],
    }

used ugly patch, but it works for me. I have no idea how puppet searches all module files so used a fast working way =)

--- modules/portage/lib/puppet/type/package_keywords.rb     2013-07-09 18:35:00.066288663 +0400
+++ modules/portage/lib/puppet/type/package_keywords.rb 2013-07-09 18:35:25.389492325 +0400
@@ -1,4 +1,4 @@
-require 'puppet/util/portage'
+require File.join(File.dirname(File.realpath(File.dirname(__FILE__))),'util/portage')

 Puppet::Type.newtype(:package_keywords) do
   @doc = "Set keywords for a package.

wrong permissions in package.*/* files

Files created under package.* have permissions 600 while they should be 644. The reason is that eix gets confused with those permissions for some reason, and the provider is reporting wrong version as latest one.

portage::package require =>

portage::package needs a requre option:

    portage::package {'dev-php/pecl-sphinx':
        ensure   => present,
        keywords => ['~amd64', '~x86'],
        require => Package['dev-lang/php'],
    }

Missing requires for mask, unmask, and use types

The Portage util methods aren't being required for all types. Because of this there could be a race condition in loading where if the keywords type wasn't being loaded first then the other types would fail.

Spec failures on 2.x branch

Probably related to fix #24

Failures:

  1) Puppet::Type::Package_keywords::ProviderParsed when flushing should write an atom name to disk
     Failure/Error: @providerinstance.flush
     Errno::ENOENT:
       No such file or directory - /etc/portage/package.keywords/default
     # ./lib/puppet/provider/portagefile.rb:16:in `chmod'
     # ./lib/puppet/provider/portagefile.rb:16:in `flush'
     # ./spec/unit/provider/package_keywords/parsed_spec.rb:59:in `block (3 levels) in '

  2) Puppet::Type::Package_keywords::ProviderParsed when flushing should write a single keyword to disk
     Failure/Error: @providerinstance.flush
     Errno::ENOENT:
       No such file or directory - /etc/portage/package.keywords/default
     # ./lib/puppet/provider/portagefile.rb:16:in `chmod'
     # ./lib/puppet/provider/portagefile.rb:16:in `flush'
     # ./spec/unit/provider/package_keywords/parsed_spec.rb:65:in `block (3 levels) in '

  3) Puppet::Type::Package_keywords::ProviderParsed when flushing should write an array of keywords to disk
     Failure/Error: @providerinstance.flush
     Errno::ENOENT:
       No such file or directory - /etc/portage/package.keywords/default
     # ./lib/puppet/provider/portagefile.rb:16:in `chmod'
     # ./lib/puppet/provider/portagefile.rb:16:in `flush'
     # ./spec/unit/provider/package_keywords/parsed_spec.rb:71:in `block (3 levels) in '

  4) Puppet::Type::Package_unmask::ProviderParsed when flushing should write an atom name to disk
     Failure/Error: @providerinstance.flush
     Errno::ENOENT:
       No such file or directory - /etc/portage/package.unmask/default
     # ./lib/puppet/provider/portagefile.rb:16:in `chmod'
     # ./lib/puppet/provider/portagefile.rb:16:in `flush'
     # ./spec/unit/provider/package_unmask/parsed_spec.rb:44:in `block (3 levels) in '

  5) Puppet::Type::Package_use::ProviderParsed when flushing should write an atom name to disk
     Failure/Error: @providerinstance.flush
     Errno::ENOENT:
       No such file or directory - /etc/portage/package.use/default
     # ./lib/puppet/provider/portagefile.rb:16:in `chmod'
     # ./lib/puppet/provider/portagefile.rb:16:in `flush'
     # ./spec/unit/provider/package_use/parsed_spec.rb:59:in `block (3 levels) in '

  6) Puppet::Type::Package_use::ProviderParsed when flushing should write a single use to disk
     Failure/Error: @providerinstance.flush
     Errno::ENOENT:
       No such file or directory - /etc/portage/package.use/default
     # ./lib/puppet/provider/portagefile.rb:16:in `chmod'
     # ./lib/puppet/provider/portagefile.rb:16:in `flush'
     # ./spec/unit/provider/package_use/parsed_spec.rb:65:in `block (3 levels) in '

  7) Puppet::Type::Package_use::ProviderParsed when flushing should write an array of use to disk
     Failure/Error: @providerinstance.flush
     Errno::ENOENT:
       No such file or directory - /etc/portage/package.use/default
     # ./lib/puppet/provider/portagefile.rb:16:in `chmod'
     # ./lib/puppet/provider/portagefile.rb:16:in `flush'
     # ./spec/unit/provider/package_use/parsed_spec.rb:71:in `block (3 levels) in '

Finished in 0.08944 seconds
112 examples, 7 failures

Failed examples:

rspec ./spec/unit/provider/package_keywords/parsed_spec.rb:58 # Puppet::Type::Package_keywords::ProviderParsed when flushing should write an atom name to disk
rspec ./spec/unit/provider/package_keywords/parsed_spec.rb:63 # Puppet::Type::Package_keywords::ProviderParsed when flushing should write a single keyword to disk
rspec ./spec/unit/provider/package_keywords/parsed_spec.rb:69 # Puppet::Type::Package_keywords::ProviderParsed when flushing should write an array of keywords to disk
rspec ./spec/unit/provider/package_unmask/parsed_spec.rb:43 # Puppet::Type::Package_unmask::ProviderParsed when flushing should write an atom name to disk
rspec ./spec/unit/provider/package_use/parsed_spec.rb:58 # Puppet::Type::Package_use::ProviderParsed when flushing should write an atom name to disk
rspec ./spec/unit/provider/package_use/parsed_spec.rb:63 # Puppet::Type::Package_use::ProviderParsed when flushing should write a single use to disk
rspec ./spec/unit/provider/package_use/parsed_spec.rb:69 # Puppet::Type::Package_use::ProviderParsed when flushing should write an array of use to disk

trigger rebuild after package_* addition/edit

Currently I have implemented some code in portage::package in my fork to rebuild every time one of the package_* entries are touched. It would be better though if we add a new parameter in the provider, so we can do something like:

package_keywords { 'app-admin/puppet':
  keywords => '~x86',
  target => 'puppet',
  rebuild => true,
}

Default value should be false, in order to avoid useless rebuilds
The command that should be triggered is /usr/bin/emerge -u1 --changed-use ${name}

package_use always updates conditional USEs

See https://github.com/Flameeyes/puppet-flameeyes/blob/master/manifests/puppet.pp (I know it's redundant).

There's a package_use declared for app-admin/puppet which adds $master_use, which is either minimal or not depending on whether I'm going to run master or not. But even if I don't change it I get this:

Notice: /Stage[main]/Flameeyes::Puppet/Package_use[app-admin/puppet]/use: use changed 'shadow minimal' to 'shadow minimal'

every time I run puppet agent --test.

Remove legacy defines

Defines like gentoo::mask are legacy and should be removed in favor of the native types and providers.

automatically convert old package.* files to dirs

The portage module on its first run should:

  1. Check if /etc/portage/package.$type exists
  2. If it doesn't exist, create a dir, else check if it is a file or dir
  3. If it is a file, then replace it with a dir and put the old content to /etc/portage/package.$type/old

Let's skip that for the next major version though

Support sourcing files in make.conf

For layman for instance we usually use source /var/lib/layman/make.conf to load an external file. This is currently impossible to express.

Support for /etc/portage/package.env

It's pretty common for packages to need specific environment variables at install time (i.e. to set MAKEOPTS, disable DistCC, or use safer CFLAGS). It would be great to see this module with the ability to modify /etc/portage/env files as well as /etc/portage/package.env like the other package.* directories.

package_* types do not update version when it was not initially defined

package_mask { 'media-sound/amarok': }

This creates an entry media-sound/amarok in /etc/portage/package.mask/default. On a second run:

package_mask { 'media-sound/amarok':
  version => '=2.5.0',
}

This does NOT update the entry to =media-sound/amarok-2.5.0

This bug affects only the version attribute on all package_* types. It does NOT affect keywords,use,ensure,target.

Error 400 on SERVER: Could not autoload puppet/type/package_keywords

Hi there,

i installed your module via "puppet module install adrien/portage" on the puppetmaster. This is a fresh install.
in my site.pp i have the following lines:

portage::package { 'app-admin/puppet':
    use         => ['vim-syntax', 'augeas'],
    use_version => '3.1.1',
    keywords    => '~amd64',
    ensure      => '3.1.1',
}

During a puppet run i got the following error:
Error: Could not retrieve catalog from remote server: Error 400 on SERVER: Could not autoload puppet/type/package_keywords: cannot load such file -- puppet/util/portage on node puppettest.domain.de

Module namespacing is wrong

This module was renamed from gentoo to portage but the package names were not updated. They should be changed to portage so that the autoloader can find them.

add support for eselect

I haven't thought yet how this should be implemented, I'm just opening the ticket so that I don't forget it. It is probably possible to be done through a new define, but it may need a new type/provider.

(portage::)eselect { 'ruby':
  set => "ruby18"
}

Support for portage sets

It would be very useful if this module could be used to install/uninstall portage sets.

/var/lib/portage/world_sets shows which sets are currently installed and this can be referenced against the contents of /etc/portage/sets/ to see if a set is available but not installed. Exec 'emerge -n @my-set' could then be called to install anything which has been added to a set file after the initial install.

exec rebuild_$name does not handle the version

exec rebuild_${name} (in portage::package) should run emerge --changed-use -u1 ${handler}${name}-${version}, eg emerge --changed-use -u1 =app-admin/puppet-3.2.1.

The problem is that without the version it tries to rebuild the latest available package instead of the one specified in portage::package

package_{use,keywords} ignores use/keywords attribute

reproducer:

package_keywords { 'kde-base/kdelibs':
  keywords => '~amd64',
}
package_use { 'kde-base/kdelibs':
  use => 'test',
}

The files /etc/portage/package.{keywords,use}/default contain an entry kde-base/kdelibs without the specified useflags/keywords. A second puppet agent run fixes the issue

package_mask fails with a ruby error

The manifest is:

package_mask { 'www-client/firefox':
    version => '23.0',
}

The relevant puppet agent output is:

Debug: Prefetching parsed resources for package_mask
Notice: /Stage[main]//Node[localhost.h4.iitk.ac.in]/Package_mask[www-client/firefox]/ensure: created
Debug: Flushing package_mask provider target /etc/portage/package.mask/default
Error: /Stage[main]//Node[localhost.h4.iitk.ac.in]/Package_mask[www-client/firefox]: Could not evaluate: can't convert nil into String

This blocks #51 #84

package_{mask,unmask,keywords} entries don't get added without any attributes specified

package_mask {'app-admin/puppet': }

The above gets ignored, while it should produce an entry app-admin/puppet in /etc/portage/package.mask/default. Same behavior for package_unmask and package_keywords types.

The above functionality should NOT be enabled for package_use though, as in this file an entry without useflags next to it makes no sense. (in case such an entry is in package.use though, there is no error thrown by portage, so we are free not to care much here)

multiple duplicate keyword/useflag entries created

package_use { 'app-admin/puppet':
  use    => 'random',
  target => 'test',
}
package_use {'dev-ruby/facter':
  use    => 'something',
  target => 'test',
}

The above snippet ends to the following result in /etc/portage/package.use/test:

app-admin/puppet random random
dev-ruby/facter something

Pay attention to the double random there. I noticed that the second random gets there as soon as the second package_use gets executed. A third package_use entry results to having three times the same useflag set in the first entry, two times in the second and one in the third. The same behavior happens in package_keywords as well

package_* should always use default values when their attributes are not explicitly specified

package_keywords { 'app-admin/puppet':
  keywords => '~amd64',
  ensure => present,
}

The above creates an entry app-admin/puppet ~amd64 in /etc/portage/package.keywords/default. On a second run:

package_keywords { 'app-admin/puppet':
  ensure => present
}

The above does nothing, while I would expect for it to remove the keywords from the previously created entry. The workaround to this is to write:

package_keywords { 'app-admin/puppet':
  keywords => '',
  ensure => present,
}

Difference between explicitly declared "ensure => latest" and default in portage::package?

I'm using the 2.x branch and did the following:

I started with the latest version of a package (1.0.2 - but not explicitly declared just portage::package {'foo':}) then i changed it to "ensure => 1.0.1". That worked fine, but as i removed the "ensure => 1.0.1" the latest version wasn't installed. I had to explicitly add "ensure => latest".

Is this behaviour intended?

Cheers,
Patryk

eselect require => ...

I think it`s a good idea to modify eselect so it can support "require" option.

eselect {'php':
    set => 'fpm php5.3',
    require => Package['dev-lang/php']
}

How to ensure that make.conf content is defined before installing packages?

I tried to put a portage::makeconf entry in a stage before 'main', but it fails :

err: Could not apply complete catalog: Found 1 dependency cycle:
(File[/var/lib/puppet/concat/_etc_portage_make.conf/fragments/10_MAKEOPTS] => Concat::Fragment[MAKEOPTS] => Portage::Makeconf[MAKEOPTS] => Class[Gentoo-node] => Stage[first] => Stage[main] => Class[Portage] => Concat[/etc/portage/make.conf] => File[/var/lib/puppet/concat/_etc_portage_make.conf/fragments] => File[/var/lib/puppet/concat/_etc_portage_make.conf/fragments/10_MAKEOPTS])

What's the recommended way to ensure that make.conf content is defined before emerging any package?

Thanks!

package_use does not remove entries

Steps to reproduce:

  1. Add a package_use entry:
package_use { "sys-process/htop":
  use => "unicode",
  target => "htop",
}
  1. Run puppet agent
  2. Remove the entry
  3. Run agent again

The entry is still there in /etc/portage/package.use/htop, while it should be removed. Ideally, if the file does not have any other entries, it should be removed as well.

puppet-lint warnings and errors

% puppet-lint --with-filename .
./modules/portage/tests/package_use.pp - WARNING: class not documented on line 1
./modules/portage/tests/package_use.pp - WARNING: class not documented on line 21
./modules/portage/tests/package_use.pp - ERROR: test not in autoload module layout on line 1
./modules/portage/tests/package_use.pp - ERROR: test::change not in autoload module layout on line 21
./modules/portage/tests/package_use.pp - WARNING: double quoted string containing no variables on line 5
./modules/portage/tests/package_use.pp - WARNING: double quoted string containing no variables on line 9
./modules/portage/tests/package_use.pp - WARNING: double quoted string containing no variables on line 10
./modules/portage/tests/package_use.pp - WARNING: double quoted string containing no variables on line 15
./modules/portage/tests/package_use.pp - WARNING: double quoted string containing no variables on line 17
./modules/portage/tests/package_use.pp - WARNING: double quoted string containing no variables on line 22
./modules/portage/tests/package_use.pp - WARNING: double quoted string containing no variables on line 22
./modules/portage/tests/package_keywords.pp - WARNING: double quoted string containing no variables on line 3
./modules/portage/tests/package_keywords.pp - WARNING: double quoted string containing no variables on line 7
./modules/portage/tests/package_keywords.pp - WARNING: double quoted string containing no variables on line 8
./modules/portage/tests/package_keywords.pp - WARNING: double quoted string containing no variables on line 12
./modules/portage/tests/package_keywords.pp - WARNING: double quoted string containing no variables on line 14
./modules/portage/tests/package_keywords.pp - WARNING: double quoted string containing no variables on line 18
./modules/portage/tests/package_keywords.pp - WARNING: double quoted string containing no variables on line 19
./modules/portage/tests/package_use-change.pp - WARNING: double quoted string containing no variables on line 3
./modules/portage/tests/package_use-change.pp - WARNING: double quoted string containing no variables on line 5
./modules/portage/manifests/makeconf.pp - WARNING: defined type not documented on line 1
./modules/portage/manifests/makeconf.pp - WARNING: ensure found on line but it's not the first attribute on line 15
./modules/portage/manifests/makeconf.pp - WARNING: ensure found on line but it's not the first attribute on line 24
./modules/portage/manifests/makeconf.pp - WARNING: double quoted string containing no variables on line 2
./modules/portage/manifests/makeconf.pp - WARNING: double quoted string containing no variables on line 3
./modules/portage/manifests/makeconf.pp - WARNING: double quoted string containing no variables on line 4
./modules/portage/manifests/makeconf.pp - WARNING: double quoted string containing no variables on line 16
./modules/portage/manifests/postsync.pp - WARNING: defined type not documented on line 1
./modules/portage/manifests/postsync.pp - WARNING: mode should be represented as a 4 digit octal value or symbolic mode on line 5
./modules/portage/manifests/postsync.pp - WARNING: => is not properly aligned on line 4
./modules/portage/manifests/postsync.pp - WARNING: => is not properly aligned on line 6
./modules/portage/manifests/postsync.pp - WARNING: => is not properly aligned on line 7
./modules/portage/manifests/postsync.pp - WARNING: unquoted file mode on line 5
./modules/portage/manifests/postsync.pp - WARNING: ensure found on line but it's not the first attribute on line 6
./modules/portage/manifests/postsync.pp - WARNING: double quoted string containing no variables on line 4
./modules/portage/manifests/postsync.pp - WARNING: double quoted string containing no variables on line 7
./modules/portage/manifests/params.pp - WARNING: class not documented on line 1
./modules/portage/manifests/params.pp - WARNING: double quoted string containing no variables on line 7
./modules/portage/manifests/params.pp - WARNING: double quoted string containing no variables on line 8
./modules/portage/manifests/params.pp - WARNING: double quoted string containing no variables on line 9
./modules/portage/manifests/params.pp - WARNING: double quoted string containing no variables on line 13
./modules/portage/manifests/init.pp - WARNING: class inheriting from params class on line 11
./modules/portage/manifests/init.pp - WARNING: class not documented on line 1
./modules/portage/manifests/init.pp - WARNING: => is not properly aligned on line 37
./modules/portage/manifests/init.pp - WARNING: double quoted string containing no variables on line 22
./modules/portage/manifests/init.pp - WARNING: double quoted string containing no variables on line 24
./modules/portage/manifests/init.pp - WARNING: double quoted string containing no variables on line 26
./modules/portage/manifests/init.pp - WARNING: double quoted string containing no variables on line 28
./modules/portage/manifests/init.pp - WARNING: double quoted string containing no variables on line 30
./modules/portage/manifests/init.pp - WARNING: double quoted string containing no variables on line 34
./modules/portage/manifests/init.pp - WARNING: double quoted string containing no variables on line 35
./modules/portage/manifests/init.pp - WARNING: double quoted string containing no variables on line 44
./modules/portage/manifests/init.pp - WARNING: double quoted string containing no variables on line 47
./modules/portage/manifests/init.pp - WARNING: double quoted string containing no variables on line 49
./modules/portage/manifests/package.pp - WARNING: variable not enclosed in {} on line 53
./modules/portage/manifests/package.pp - WARNING: defined type not documented on line 1
./modules/portage/manifests/package.pp - WARNING: double quoted string containing no variables on line 50
./modules/portage/manifests/package.pp - WARNING: double quoted string containing no variables on line 52
./modules/portage/manifests/package.pp - WARNING: top-scope variable being used without an explicit namespace on line 33
./modules/portage/manifests/package.pp - WARNING: top-scope variable being used without an explicit namespace on line 39
./modules/base/manifests/hosts.pp - WARNING: double quoted string containing no variables on line 2
./modules/base/manifests/hosts.pp - WARNING: double quoted string containing no variables on line 3
./modules/base/manifests/hosts.pp - WARNING: double quoted string containing no variables on line 6
./modules/base/manifests/hosts.pp - WARNING: double quoted string containing no variables on line 7
./modules/base/manifests/hosts.pp - WARNING: double quoted string containing no variables on line 8
./modules/base/manifests/hosts.pp - WARNING: double quoted string containing no variables on line 10
./modules/base/manifests/hosts.pp - WARNING: double quoted string containing no variables on line 11
./modules/base/manifests/hosts.pp - WARNING: double quoted string containing no variables on line 12
./modules/base/manifests/hosts.pp - WARNING: double quoted string containing no variables on line 14
./modules/base/manifests/hosts.pp - WARNING: double quoted string containing no variables on line 15
./modules/base/manifests/hosts.pp - WARNING: double quoted string containing no variables on line 16
./modules/base/manifests/hosts.pp - WARNING: double quoted string containing no variables on line 18
./modules/base/manifests/hosts.pp - WARNING: double quoted string containing no variables on line 19
./modules/base/manifests/hosts.pp - WARNING: double quoted string containing no variables on line 20
./modules/base/manifests/hosts.pp - WARNING: double quoted string containing no variables on line 22
./modules/base/manifests/hosts.pp - WARNING: double quoted string containing no variables on line 23
./modules/base/manifests/hosts.pp - WARNING: double quoted string containing no variables on line 24
./modules/base/manifests/hosts.pp - WARNING: double quoted string containing no variables on line 26
./modules/base/manifests/hosts.pp - WARNING: double quoted string containing no variables on line 27
./modules/base/manifests/hosts.pp - WARNING: double quoted string containing no variables on line 28
./modules/base/manifests/hosts.pp - WARNING: double quoted string containing no variables on line 29
./modules/base/manifests/hosts.pp - WARNING: double quoted string containing no variables on line 30
./modules/base/manifests/hosts.pp - WARNING: double quoted string containing no variables on line 33
./modules/base/manifests/hosts.pp - WARNING: double quoted string containing no variables on line 34
./modules/base/manifests/hosts.pp - WARNING: double quoted string containing no variables on line 35
./modules/base/manifests/hosts.pp - WARNING: double quoted string containing no variables on line 37
./modules/base/manifests/hosts.pp - WARNING: double quoted string containing no variables on line 38
./modules/base/manifests/hosts.pp - WARNING: double quoted string containing no variables on line 39
./modules/base/manifests/hosts.pp - WARNING: double quoted string containing no variables on line 41
./modules/base/manifests/hosts.pp - WARNING: double quoted string containing no variables on line 42
./modules/base/manifests/hosts.pp - WARNING: double quoted string containing no variables on line 43
./modules/base/manifests/hosts.pp - WARNING: top-scope variable being used without an explicit namespace on line 4
./modules/concat/manifests/setup.pp - WARNING: double quoted string containing no variables on line 25
./modules/concat/manifests/setup.pp - WARNING: line has more than 80 characters on line 25
./modules/concat/manifests/setup.pp - WARNING: line has more than 80 characters on line 28
./modules/concat/manifests/fragment.pp - WARNING: line has more than 80 characters on line 16
./modules/concat/manifests/init.pp - WARNING: double quoted string containing no variables on line 156
./modules/concat/manifests/init.pp - WARNING: double quoted string containing no variables on line 156
./modules/concat/manifests/init.pp - WARNING: line has more than 80 characters on line 232
./modules/concat/manifests/init.pp - WARNING: line has more than 80 characters on line 240
./modules/concat/manifests/init.pp - WARNING: quoted boolean value found on line 145
./modules/concat/manifests/init.pp - WARNING: quoted boolean value found on line 148
./modules/concat/manifests/init.pp - WARNING: quoted boolean value found on line 163
./modules/concat/manifests/init.pp - WARNING: quoted boolean value found on line 166

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.