Compare commits

...

498 Commits

Author SHA1 Message Date
cd30bedd2b system: some user inmprovements
* not use cgo
* add lock/unlock user

Signed-off-by: Vasiliy Tolstov <v.tolstov@selfip.ru>
2015-11-25 11:26:00 +00:00
Jonathan Boulle
fa0178cd47 Merge pull request #400 from sethp/coreos-cloudinit/gzip-magic
gzip autodetection
2015-11-11 13:49:14 -08:00
Seth Pellegrino
778a47b957 userdata: gzip autodetection
look for the gzip magic number at the beginning of a data source, and,
if found, decompress the input before further processing.

Addresses coreos/bugs#741.
2015-11-11 08:21:00 -08:00
Seth Pellegrino
86909e5bcb test: added coreos-cloudinit_test to test script
Include the root project directory in packages
to be built/tested.
2015-11-11 08:06:36 -08:00
Josh Wood
0fd3cd2fae Merge pull request #406 from joshix/doubledash0
Vmware-guestinfo: Double hyphen long options.
2015-11-10 10:21:06 -08:00
Josh Wood
ad81cf7f78 Vmware-guestinfo: Double hyphen long options.
In line with https://github.com/coreos/docs/issues/650,
revert a little bit of https://github.com/coreos/coreos-cloudinit/pull/404
to document `--longoption` with two hyphens in document and Usage.
2015-11-09 16:31:30 -08:00
Josh Wood
0a500a19ff Merge pull request #405 from omkensey/doc-link-blob-fix
docs: fix links to specific blobs
2015-11-08 23:54:34 -08:00
Joe Thompson
b9f34d93ad docs: fix links to specific blobs
Rather than link to specific blob hashes, now that things have been synced to 0.4.9 we can link to the 0.4 release for original etcd; also fixes a link that was to a blob hash of configuration.md instead of the head of master for etcd.
2015-11-09 02:05:37 -05:00
Josh Wood
2f5d8cc188 Merge pull request #404 from joshix/backdoorname
Docs/vmware-backdoor: Rename backdoor to guestinfo
2015-11-05 15:35:45 -08:00
Josh Wood
b56c0f5609 Docs/vmware-backdoor: Rename backdoor to guestinfo
Based on results of google searches on a few possible titles
to improve on the connotation of backdoor, Guestinfo Configuration
Interface (as part of the RPC API) seems recognizable in vmware
circles. Friends call it just guestinfo.

This changeset also makes docs and usage for this flag appear with
a single hypen (-flag) like most go programs do.
2015-11-05 15:27:33 -08:00
Alex Crawford
cd1994b007 Merge pull request #403 from mdlayher/digitalocean_anchor_gateway
network: do not assign gateway for DigitalOcean anchor IP address
2015-10-27 09:10:34 -07:00
Matt Layher
1fd780befc network: do not assign gateway for DigitalOcean anchor IP address 2015-10-27 10:49:05 -04:00
Rob Szumski
8847a471c5 Merge pull request #393 from endocode/kayrus/vmware
Updated vmware info / Fixed help help message
2015-10-21 09:20:59 -07:00
kayrus
c0c144bd56 Added additional vmware info, fixed cli help 2015-10-19 10:33:27 +02:00
Alex Crawford
1d962916b9 Merge pull request #402 from xiang90/etcd2_wal
config: add wal_dir into etcd2.go
2015-10-15 12:29:49 -07:00
Xiang Li
bda6668f00 config: add wal_dir into etcd2.go 2015-10-15 09:36:48 -07:00
Alex Crawford
0f828db9a3 Merge pull request #401 from mischief/update-fleet-options
config: sync fleet options
2015-10-14 11:05:17 -07:00
Nick Owens
5970000589 config: sync fleet options 2015-10-14 11:02:59 -07:00
Alex Crawford
7870fa8c9d Merge pull request #399 from mdlayher/digitalocean_floatingip
datasource, network: add support for DigitalOcean floating IPs
2015-10-13 11:59:46 -07:00
Matt Layher
b4d45306b2 datasource, network: add support for DigitalOcean floating IPs 2015-10-09 10:52:05 -04:00
Michael Marineau
3c2b5e6636 Merge pull request #398 from marineam/gomax
main: default to GOMAXPROCS=1
2015-09-30 20:43:03 -07:00
Michael Marineau
bf743b3060 main: default to GOMAXPROCS=1 2015-09-30 17:23:40 -07:00
Jonathan Boulle
3b98be7788 Merge pull request #396 from crawford/bugs
readme: add link to coreos/bugs
2015-09-24 19:44:48 -07:00
Alex Crawford
746685023f readme: add link to coreos/bugs 2015-09-24 17:50:06 -07:00
Alex Crawford
a0fcbb16d6 Merge pull request #395 from crawford/locksmith
config: add group and window options for locksmith
2015-09-23 23:21:19 -07:00
Alex Crawford
f63fa39a2d config: format license 2015-09-23 23:19:47 -07:00
Alex Crawford
0ae90f3b22 config: add group and window options for locksmith
The regular expression for RebootWindowLength comes from
https://golang.org/pkg/time/#ParseDuration.
2015-09-23 23:19:41 -07:00
Alex Crawford
dee67b964a Merge pull request #385 from endocode/kayrus/fleet
doc: added coreos-cloudinit options description
2015-09-21 10:32:20 -07:00
Michael Marineau
05062188f1 Merge pull request #391 from marineam/go-1.5.1
Fix and enable testing on Go 1.5
2015-09-16 17:34:43 -07:00
Michael Marineau
5405fc9d0d network: update error check for Go 1.5
Changed upstream:
055ecb7be5
2015-09-16 13:26:21 -07:00
Michael Marineau
c7f327bb89 travis: enable go 1.5 2015-09-16 13:02:45 -07:00
Alex Crawford
71e2b2bddb Merge pull request #389 from stresler/patch-1
cloudinit: Removing convert-netconf from Packet OEM
2015-09-11 09:13:10 -07:00
stresler
8fac253214 Removing convert-netconf from packet OEM
We still utilize the network code on first boot, so it should remain until we implement ignition, but we don't want it on subsequent boots, which is what this line would do.
2015-09-11 12:00:10 -04:00
Alex Crawford
e19fd09664 Merge pull request #386 from crawford/quotes
docs: quote everything
2015-09-08 18:45:52 -07:00
Alex Crawford
4a25948b53 docs: quote everything
I realize this is one of the selling points of YAML, but it causes far
too much confusion. Turns out typing is a good thing.
2015-09-08 18:40:21 -07:00
kayrus
f5cc75299a doc: added coreos-cloudinit options description 2015-09-08 12:23:10 +02:00
Michael Marineau
f816819c6d Merge pull request #380 from endocode/kayrus/mod_cloudinit_locations
Filled cloud providers cloud-config URLs
2015-09-07 10:41:49 -07:00
Alex Crawford
5f688a0a21 Merge pull request #379 from endocode/kayrus/trim_fix
cloudinit: trim trailing whitespaces in #cloud-config header
2015-09-07 10:09:42 -07:00
kayrus
f92dcb7968 cloudinit: trim trailing whitespaces in #cloud-config header 2015-09-07 18:30:02 +02:00
Alex Crawford
bb71f5e072 Merge pull request #383 from sigma/t/feature/vmware-config-url
datasource/vmware: introduce guestinfo.coreos.config.url
2015-09-04 09:20:42 -07:00
Yann Hodique
ed512c1cac datasource/vmware: introduce guestinfo.coreos.config.url
allow use of a URL instead of an inline document.
Inline document takes precedence.
2015-09-03 20:50:19 -07:00
Alex Crawford
94f8e00054 Merge pull request #382 from sigma/t/fix/assertion
datasource/vmware: fix assertion
2015-09-03 18:39:22 -07:00
Yann Hodique
b5cb942acb datasource/vmware: fix assertion
we definitely don't always want nil
2015-09-03 18:15:23 -07:00
Rob Szumski
de38ac5c98 Merge pull request #381 from endocode/kayrus/new_docs
docs: added cloud-config headers explanation
2015-09-02 08:54:28 -07:00
kayrus
dfc5f2627f Added cloud-config headers explanation 2015-09-02 15:12:27 +02:00
Alex Crawford
057e8094d5 Merge pull request #345 from crawford/vmware
datasource: add vmware backdoor
2015-09-01 15:41:01 -07:00
Alex Crawford
15b50d4712 doc: Add docs for VMware backdoor 2015-09-01 15:36:36 -07:00
Alex Crawford
dda5032296 cloudinit: add vmware backdoor 2015-09-01 15:36:36 -07:00
Alex Crawford
d675638776 datasource: add vmware 2015-09-01 15:36:35 -07:00
kayrus
61e3595520 Added table for cloud-config locations 2015-08-31 12:04:23 +02:00
kayrus
4f76283917 Filled cloud providers cloud-config URLs 2015-08-28 12:58:00 +02:00
Rob Szumski
9c4aca6c9a Merge pull request #366 from endocode/master
docs: add cloud-config locations
2015-08-26 10:06:26 -04:00
Alex Crawford
13dc11abf3 godeps: add github.com/sigma/vmw-guestinfo 2015-08-24 09:03:29 -07:00
Alex Crawford
9ba25550a1 datasource: use opaque object instead of string
Rather than serializing the network config into a string and then later
deserializing it, just pass the object through directly.
2015-08-24 09:03:29 -07:00
Alex Crawford
81ffa056bd log: use log.Print instead of fmt.Print 2015-08-23 19:30:03 -07:00
kayrus
8c804a1124 Removed {{site.baseurl}} 2015-08-18 11:31:52 +02:00
kayrus
0a46b32c88 Updated cloudconfig docs
* Fixed openstack config-drive link
* Added cloud-config-locations.md
2015-08-17 16:53:33 +02:00
Alex Crawford
fac805dc11 Merge pull request #375 from crawford/build
build: extract the version number from git
2015-08-12 11:09:29 -07:00
Alex Crawford
94ea0b99ea Merge pull request #374 from crawford/timeout
pkg/http: up the timeout to 10 seconds
2015-08-12 11:08:04 -07:00
Alex Crawford
56a80d84cf build: extract the version number from git
Update the tests as well.
2015-08-12 11:05:04 -07:00
Alex Crawford
00c9174da4 pkg/http: up the timeout to 10 seconds
Additionally, fix the units on that multiplication. This isn't
acceleration.
2015-08-11 10:42:41 -07:00
Alex Crawford
ec8742c9ba Merge pull request #371 from crawford/http-client
pkg: update HttpClient to use newer Go features
2015-08-07 20:03:01 -07:00
Alex Crawford
b3b09aeb19 pkg: update HttpClient to use newer Go features 2015-08-07 19:30:47 -07:00
Alex Crawford
481d98c0b5 Merge pull request #370 from crawford/etcd2
config: update flags for etcd 2.1
2015-08-07 17:03:43 -07:00
Alex Crawford
f30727a675 config: update flags for etcd 2.1 2015-08-07 16:20:36 -07:00
kayrus
fc4efb086b Merge https://github.com/coreos/coreos-cloudinit 2015-07-28 14:40:18 +02:00
kayrus
5383bd1f07 Fixed Cloud-Config examples 2015-07-27 18:29:21 +02:00
Alex Crawford
e1305937e6 Merge pull request #362 from bodgit/mkisofs
Add note for creating config-drive ISO on OS X
2015-07-23 18:42:37 -07:00
Alex Crawford
20c4653ecf Merge pull request #365 from cusspvz/flannel/add-public-ip-opt
Add PublicIP option on flannel
2015-07-23 13:41:06 -07:00
José Moreira
43c6da06a5 add public_ip opt on cloud-config.md 2015-07-23 17:04:37 +01:00
José Moreira
7ab84601c3 Add PublicIP opt 2015-07-22 22:54:03 +01:00
Alex Crawford
a24b23663c Merge pull request #364 from crawford/etcd
config: specific valid values for ETCD_PROXY
2015-07-21 22:21:25 -07:00
Alex Crawford
91fe744bd2 config: specific valid values for ETCD_PROXY 2015-07-21 14:20:10 -07:00
Matt Dainty
eb8fc045ee Add note for creating config-drive ISO on OS X 2015-07-20 10:27:02 +01:00
Alex Crawford
ba83b2871f coreos-cloudinit: bump to v1.5.0+git 2015-07-14 11:55:39 -07:00
Alex Crawford
f36821f7ce coreos-cloudinit: bump to v1.5.0 2015-07-14 11:54:56 -07:00
Alex Crawford
97fe210760 Merge pull request #356 from crawford/ignition
config: recognize Ignition configs and no-op
2015-07-10 16:34:18 -07:00
Alex Crawford
c6400f7751 config: recognize Ignition configs and no-op 2015-07-10 16:32:57 -07:00
Alex Crawford
f6647634f0 Merge pull request #352 from packethost/packet-datasource
datasource: add packethost metadata
2015-07-10 12:25:37 -07:00
Sam Tresler
837d3d3622 datasource: add packethost metadata 2015-07-10 15:13:57 -04:00
Alex Crawford
1063a4b9ee Merge pull request #351 from packethost/bond-config-options
Bond options persisted to the generated netdev file.
2015-07-10 09:08:31 -07:00
Sam Tresler
081f77a102 Persisting bond options to the netdev file, and updating the test. 2015-06-23 11:21:26 -04:00
Alex Crawford
41289286ca Merge pull request #354 from packethost/go-ci-versions
Go ci versions
2015-06-22 16:04:56 -07:00
Sam Tresler
d50a4069a6 Removing goland 1.3 and 1.2 from Travis testing 2015-06-22 18:43:27 -04:00
Alex Crawford
be0c9c56e4 Merge pull request #347 from crawford/import
doc: deprecate coreos-ssh-import-*
2015-05-28 13:45:02 -07:00
Alex Crawford
6467f06656 doc: deprecate coreos-ssh-import-* 2015-05-28 13:35:51 -07:00
Alex Crawford
7a05e63fcc coreos-cloudinit: bump to v1.4.1+git 2015-05-12 17:08:27 -07:00
Alex Crawford
ca6f97d050 coreos-cloudinit: bump to v1.4.1 2015-05-12 17:08:06 -07:00
Alex Crawford
d086bca9e4 Merge pull request #336 from crawford/doc
docs: fix typo with etcd2 env vars
2015-04-28 13:48:05 -07:00
Alex Crawford
d25f18776f docs: fix typo with etcd2 env vars 2015-04-27 18:03:13 -07:00
Alex Crawford
c583b77cdb Merge pull request #335 from crawford/github
config: deprecate fetching SSH keys from remote endpoints
2015-04-20 11:29:38 -07:00
Alex Crawford
ed4d5fac4c config: deprecate fetching SSH keys from remote endpoints 2015-04-20 11:23:35 -07:00
Rob Szumski
40429204ba Merge pull request #333 from coreos/robszumski-patch-1
docs: add info about discovery size parameter
2015-04-16 12:04:49 -07:00
Rob Szumski
d72d54be59 docs: add info about discovery size parameter 2015-04-16 12:02:37 -07:00
Alex Crawford
373c7ecbd9 coreos-cloudinit: bump to v1.4.0+git 2015-04-09 17:48:36 -07:00
Alex Crawford
31c46c7051 coreos-cloudinit: bump to v1.4.0 2015-04-09 17:48:14 -07:00
Alex Crawford
66ec7d805c Merge pull request #330 from crawford/etcd
config: add support for etcd2
2015-04-07 14:40:47 -07:00
Alex Crawford
2563896f89 docs: use etcd2 instead of etcd 2015-04-07 14:24:50 -07:00
Alex Crawford
94a242cc58 config: add support for etcd2 2015-04-03 17:29:32 -07:00
Alex Crawford
5b159fcf56 coreos-cloudinit: bump to v1.3.4+git 2015-04-01 14:58:25 -07:00
Alex Crawford
a9e8940132 coreos-cloudinit: bump to v1.3.4 2015-04-01 14:58:09 -07:00
Alex Crawford
cf194ab85e Merge pull request #326 from richardmarshall/user_shell_config
config/system: add shell user attribute
2015-04-01 11:02:15 -07:00
Alex Crawford
33bc5fc63d validate: warn on deprecated keys 2015-03-30 13:52:57 -07:00
Alex Crawford
09f6a279ef config: deprecate etcd2 flags from etcd structure 2015-03-30 13:52:57 -07:00
Richard Marshall
e8c8b811fe docs: add user shell field 2015-03-06 21:12:43 -08:00
Richard Marshall
f5ecc05d62 config/system: add shell user attribute
This adds support for specifying the login shell of created users.
2015-03-06 14:16:19 -08:00
Alex Crawford
66a2f00679 coreos-cloudinit: bump to v1.3.3+git 2015-02-24 12:25:00 -08:00
Alex Crawford
14cad6f7c3 coreos-cloudinit: bump to v1.3.3 2015-02-24 12:24:37 -08:00
Alex Crawford
6f188bd5d4 Merge pull request #319 from Vladimiroff/fix-cloudsigma-empty-ssh-keys
Make sure public ssh key is not empty from CloudSigma's server context
2015-02-23 10:58:17 -08:00
Alex Crawford
41832ab19e Merge pull request #320 from ibuildthecloud/typo-contents
Fix typo, "contents" should be "content"
2015-02-23 10:41:55 -08:00
Darren Shepherd
672e4c07af Fix typo, "contents" should be "content"
The validation of the encoding for write_files was looking
for a node named "contents" when the node name is "content"

Signed-off-by: Darren Shepherd <darren@rancher.com>
2015-02-23 09:17:21 -07:00
Kiril Vladimirov
be53013431 fix(datasource/CloudSigma): Add a test for an empty ssh key 2015-02-22 05:38:57 +02:00
Kiril Vladimirov
c30fc51b03 fix(datasource/CloudSigma): Make sure public ssh key is not empty
Even when public ssh key is not set by the user, CloudSigma's server
context has a key `meta.ssh_public_key` which is just an empty string.
So instead of just relying on the "comma ok" idiom I make sure the value
is not an empty string.
2015-02-21 19:31:01 +02:00
Rob Szumski
b429eaab84 docs: fix formatting 2015-02-18 15:05:28 -08:00
Alex Crawford
e0104e6d93 coreos-cloudinit: bump to v1.3.2+git 2015-02-18 11:13:34 -08:00
Alex Crawford
7bf9712724 coreos-cloudinit: bump to v1.3.2 2015-02-18 11:12:52 -08:00
Alex Crawford
78b0f82918 Merge pull request #318 from crawford/filesystem
configdrive: correct network config reading and improve tests
2015-02-17 13:40:05 -08:00
Alex Crawford
987aa21883 configdrive: check the network config path
Check to make sure that a network config path has been specified before
trying to read from it. Otherwise, it will end up trying to read a
directory.
2015-02-17 13:27:30 -08:00
Alex Crawford
47ac4f6931 test: add directory support to MockFilesystem 2015-02-17 13:27:30 -08:00
Alex Crawford
f8aa7a43b8 coreos-cloudinit: bump to v1.3.1+git 2015-02-13 10:25:01 -08:00
Alex Crawford
2fe0b0b2a8 coreos-cloudinit: bump to v1.3.1 2015-02-13 10:24:41 -08:00
Alex Crawford
19ce7ac849 Merge pull request #317 from crawford/json
configdrive: check metadata length before parsing
2015-02-13 10:22:57 -08:00
Alex Crawford
477053ffde configdrive: check metadata length before parsing
This was lost in some of the recent refactoring.
2015-02-13 10:20:08 -08:00
Alex Crawford
eb0d2dbfa3 coreos-cloudinit: bump to v1.3.0+git 2015-02-11 17:19:32 -08:00
Alex Crawford
18caa5bf07 coreos-cloudinit: bump to v1.3.0 2015-02-11 17:19:05 -08:00
Alex Crawford
a27bbb912f Merge pull request #315 from crawford/cloudsigma
oem: add CloudSigma OEM
2015-02-11 17:15:23 -08:00
Alex Crawford
3b2af743bd oem: add CloudSigma OEM 2015-02-11 17:03:24 -08:00
Alex Crawford
995bc63abe Merge pull request #313 from jimmycuadra/etcd-2.0-configuration
Add etcd 2.0 configuration support
2015-02-09 12:33:28 -08:00
Alex Crawford
a28f870302 Merge pull request #314 from robszumski/master
docs: link to CoreUpdate and Omaha
2015-02-06 14:15:39 -08:00
Rob Szumski
a3357c273c docs: update links 2015-02-06 13:43:06 -08:00
Rob Szumski
080c698ec2 docs: link to CoreUpdate and Omaha 2015-02-06 13:31:50 -08:00
Jimmy Cuadra
afbf1dbb3a Add etcd 2.0 configuration flag support. 2015-02-05 02:57:11 -08:00
Alex Crawford
a275e18533 Merge pull request #308 from demonbane/github-capitalization
Fix GitHub capitalization
2015-01-28 14:28:53 -08:00
Alex Malinovich
cf3baa8805 Fix GitHub capitalization 2015-01-28 14:19:08 -08:00
Jonathan Boulle
ed84bcef04 Merge pull request #307 from jonboulle/master
docs: fix typo
2015-01-28 10:25:15 -08:00
Jonathan Boulle
7d8b29e597 docs: fix typo 2015-01-28 10:19:16 -08:00
Alex Crawford
4eaaa5c927 Merge pull request #304 from crawford/metadata
datasource: improve metadata handling
2015-01-27 14:36:12 -08:00
Alex Crawford
536f8acf2a config: remove network config from CloudConfig 2015-01-26 17:35:08 -08:00
Alex Crawford
9605b5edf2 datasource: remove FetchNetworkConfig step
Its easier to let each datasource grab all metadata in the FetchMetadata
stage than to break it into multiple stages.
2015-01-26 16:08:26 -08:00
Alex Crawford
42153edbbc initialize: change env to process from metadata
We don't use general substitutions so just have env pick the values it
wants to substitute.
2015-01-26 16:08:26 -08:00
Alex Crawford
650a239fdb metadata: simplify merging of metadata
Add an internal field for CloudConfig to make it easier to distinguish.
Instead of creating two CloudConfigs and merging them, just merge the
metadata into the existing CloudConfig.
2015-01-26 16:08:26 -08:00
Alex Crawford
3e47c09b41 datasource: replace metadata map with struct
The loosely-typed metadata map is a load of crap. Make it a struct and
let the compiler help us out.
2015-01-26 15:57:57 -08:00
Alex Crawford
d4c617fc23 config: standardize interface a bit 2015-01-26 15:57:55 -08:00
Alex Crawford
9441586229 test: check all root golang files 2015-01-26 15:57:54 -08:00
Alex Crawford
be62a1df66 test: DRY out MockFilesystem 2015-01-26 15:57:51 -08:00
Jonathan Boulle
c093e44049 Merge pull request #305 from jonboulle/copyright
*: switch to line comments for copyright
2015-01-25 10:28:52 -08:00
Jonathan Boulle
be68a8e5cc *: switch to line comments for copyright
Build tags are not compatible with block comments. Also adds copyright
header to a few places it was missing.
2015-01-24 19:32:33 -08:00
Alex Crawford
58b4de8093 coreos-cloudinit: bump to v1.2.1+git 2015-01-21 14:29:51 -08:00
Alex Crawford
ae3676096c coreos-cloudinit: bump to v1.2.1 2015-01-21 14:29:25 -08:00
Alex Crawford
a548b557ed doc: add coreos-ssh-import-github-users 2015-01-21 14:28:43 -08:00
Alex Crawford
a9c132a706 coreos-cloudinit: bump to v1.2.0+git 2015-01-20 14:42:48 -08:00
Alex Crawford
c3c4b86a3b coreos-cloudinit: bump to v1.2.0 2015-01-20 14:42:18 -08:00
Alex Crawford
44142ff8af Merge pull request #301 from crawford/github
config: add support for multiple github users
2015-01-20 14:26:38 -08:00
Alex Crawford
e9529ede44 config: add support for multiple github users 2015-01-20 13:45:52 -08:00
Alex Crawford
4b5b801171 Merge pull request #295 from crawford/rules
config/validate: add some sanity checks
2015-01-15 16:25:37 -08:00
Alex Crawford
551cbb1e5d config/validate: add rule for file encoding 2015-01-15 15:01:44 -08:00
Alex Crawford
3c93938f8a decode: refactor file decoding into config package 2015-01-15 15:01:44 -08:00
Alex Crawford
f61c08c246 config/validate: add rule for coreos.write_files 2015-01-15 15:01:44 -08:00
Alex Crawford
571903cec6 config/validate: add rule for etcd discovery token 2015-01-15 15:01:44 -08:00
Alex Crawford
bdbd1930ed config/validate: add rule for file paths 2015-01-15 15:01:44 -08:00
Alex Crawford
cc75a943ba Merge pull request #300 from crawford/float
validate: allow promotion of int to float64
2015-01-15 13:17:44 -08:00
Alex Crawford
fc77ba6355 validate: allow promotion of int to float64 2015-01-14 17:54:01 -08:00
Eugene Yakubovich
7cfa0df7c4 Merge pull request #299 from eyakubovich/master
config: document and update flannel config values
2015-01-13 15:55:42 -08:00
Eugene Yakubovich
58f0dadaf9 config: document and update flannel config values
Fixes #297
2015-01-13 15:51:47 -08:00
Michael Marineau
1ab530f157 Merge pull request #293 from realestate-com-au/master
select first available hostname returned by EC2 metadata.
2015-01-05 12:47:27 -08:00
Kevin Yung
13e4b77130 ec2: allow spaces seperated hostname in metadata
AWS hostname metadata will return space seperated hostname and domain
names when DHCPOptionSet is using multiple domain names. This patch will
cater for this scenario.
2015-01-05 16:01:57 +11:00
Alex Crawford
54c62cbb70 coreos-cloudinit: bump to v1.1.0+git 2014-12-30 16:52:10 +01:00
Alex Crawford
c8e864fef5 coreos-cloudinit: bump to v1.1.0 2014-12-30 16:51:24 +01:00
Alex Crawford
60a3377e7c Merge pull request #290 from crawford/yaml
Improved YAML parsing
2014-12-30 16:24:12 +01:00
Alex Crawford
5527f09778 config: fix parsing of file permissions
These reintroduces the braindead '744' syntax for file permissions. Even
though this number isn't octal, it is assumed by convention to be. In
order to pull this off, coerceNodes() was introduced to try to
counteract the type inferrencing that occurs during the yaml
unmarshalling. The config is unmarshalled twice: once into an empty
interface and once into the CloudConfig structure. The two resulting
node structures are combined together. The nodes from the CloudConfig
process replace those from the interface{} when the types of the two
nodes are compatible. For example, with the input `0744`, yaml
interprets that as the integer 484 giving us the nodes '0744'(string)
and 484(int). Because the types string and int are compatible, we opt to
take the string node instead of the integer.
2014-12-30 16:20:21 +01:00
Alex Crawford
54a64454b9 validate: fix printing for non-string values 2014-12-30 16:20:21 +01:00
Alex Crawford
0e70d4f01f config: add validity check for file permissions 2014-12-30 16:20:21 +01:00
Alex Crawford
af8e590575 config: change valid tag to use regexp
A regular expression is much more useful than a list of strings.
2014-12-30 16:20:21 +01:00
Alex Crawford
40d943fb7a reboot-strategy: remove the 'false' value
Since we no longer do a two-stage unmarshal, the 'false' value will no
longer be necessary.
2014-12-30 16:20:21 +01:00
Alex Crawford
248536a5cd config: use a YAML transform to normalize keys
This removes the problematic two-pass unmarshalling.
2014-12-30 16:20:21 +01:00
Alex Crawford
4ed1d03c97 godeps: bump github.com/coreos/yaml 2014-12-30 16:20:20 +01:00
Alex Crawford
057ab37364 config: seperate the CoreOS type from CloudConfig
Renamed Coreos to CoreOS while I was at it.
2014-12-30 16:20:20 +01:00
Alex Crawford
182241c8d3 config: clean up and remove some tests
Small modification to make these align with our test-table-style tests.
Also removed TestCloudConfigInvalidKeys since it hasn't been a useful
test since d3294bcb86.
2014-12-30 16:19:00 +01:00
Michael Marineau
edced59fa6 Merge pull request #281 from thommay/flannel_env_file
Create an environment file for flannel
2014-12-29 15:07:08 -08:00
Thom May
9be836df31 Create an environment file for flannel
Rather than using a systemd overlay, allow docker to load the
environment file. This is due to coreos/coreos-overlay#1002
2014-12-29 10:27:22 +00:00
Jonathan Boulle
4e54447b8e Merge pull request #286 from jonboulle/master
Godeps: switch to coreos/yaml
2014-12-20 15:43:55 -08:00
Jonathan Boulle
999c38b09b Godeps: switch to coreos/yaml 2014-12-20 15:31:02 -08:00
Alex Crawford
06d13de5c3 coreos-cloudinit: bump to v1.0.2+git 2014-12-12 17:38:28 -08:00
Alex Crawford
5b0903d162 coreos-cloudinit: bump to v1.0.2 2014-12-12 17:37:39 -08:00
Alex Crawford
10669be7c0 Merge pull request #284 from crawford/travis
test: disable Travis sudo capability
2014-12-12 17:28:47 -08:00
Alex Crawford
2edae741e1 test: disable Travis sudo capability 2014-12-12 16:46:18 -08:00
Alex Crawford
ea90e553d1 Merge pull request #282 from crawford/network
network: write network units with user units
2014-12-12 15:12:50 -08:00
Alex Crawford
b0cfd86902 network: write network units with user units
This allows us to test the network unit generation as well as removing
some special-cased code.
2014-12-12 15:08:03 -08:00
Alex Crawford
565a9540c9 Merge pull request #283 from crawford/validate
validate: empty user_data is also valid
2014-12-12 15:05:51 -08:00
Alex Crawford
fd10e27b99 validate: empty user_data is also valid 2014-12-12 14:49:42 -08:00
Michael Marineau
39763d772c Merge pull request #280 from marineam/go1.4
travis: Add Go 1.4 as a test target
2014-12-11 16:34:00 -08:00
Michael Marineau
ee69b77bfb travis: Add Go 1.4 as a test target 2014-12-11 15:29:36 -08:00
Jonathan Boulle
353444e56d Merge pull request #279 from cnelson/write_files_encoding_support
Add support for the encoding key to write_files
2014-12-09 17:37:34 -08:00
cnelson
112ba1e31f Added support for the encoding key in write_files
Supported encodings are base64, gzip, and base64 encoded gzip
2014-12-09 17:35:33 -08:00
cnelson
9c3cd9e69c bumped version of yaml.v1 2014-12-09 07:49:59 -08:00
Alex Crawford
685d8317bc Merge pull request #275 from mwhooker/master
Enable configuration of locksmithd
2014-12-05 14:09:40 -08:00
Matthew Hooker
f42d102b26 Also fix wording of Flannel section 2014-12-04 23:55:26 -08:00
Matthew Hooker
c944e9ef94 Enable configuration of locksmithd 2014-12-04 23:53:31 -08:00
Alex Crawford
f10d6e8bef coreos-cloudinit: bump to v1.0.1+git 2014-12-04 16:35:20 -08:00
Alex Crawford
f3f3af79fd coreos-cloudinit: bump to v1.0.1 2014-12-04 16:34:57 -08:00
Alex Crawford
0e63aa0f6b Merge pull request #276 from crawford/networkd
initialize: restart networkd before other units
2014-12-04 16:33:02 -08:00
Alex Crawford
b254e17e89 Merge pull request #263 from robszumski/docs-validator
docs: link to validator
2014-12-04 16:28:21 -08:00
Alex Crawford
5c059b66f0 initialize: restart networkd before other units 2014-12-04 15:25:44 -08:00
Alex Crawford
c628bef666 Merge pull request #273 from crawford/networkd
initialize: only restart networkd once per config
2014-12-02 12:54:27 -08:00
Alex Crawford
2270db3f7a initialize: only restart networkd once per config
Regression introduced by 9fcf338bf3.

Networkd was erroneously being restarted once per network unit. It
should only restart once for the entire config.
2014-12-02 12:46:35 -08:00
Alex Crawford
d0d467813d Merge pull request #251 from Vladimiroff/master
metadata: Populate CloudSigma's IPs properly
2014-12-01 14:52:11 -08:00
Alex Crawford
123f111efe coreos-cloudinit: bump to 1.0.0+git 2014-11-26 14:19:29 -08:00
Alex Crawford
521ecfdab5 coreos-cloudinit: bump to 1.0.0 2014-11-26 14:19:13 -08:00
Alex Crawford
6d0fdf1a47 Merge pull request #268 from crawford/dropins
drop-in: add support for drop-ins
2014-11-26 14:14:49 -08:00
Alex Crawford
ffc54b028c drop-in: add support for drop-ins
This allows a list of drop-ins for a unit to be declared inline within a
cloud-config. For example:

  #cloud-config
  coreos:
    units:
      - name: docker.service
        drop-ins:
          - name: 50-insecure-registry.conf
            content: |
              [Service]
              Environment=DOCKER_OPTS='--insecure-registry="10.0.1.0/24"'
2014-11-26 14:09:35 -08:00
Alex Crawford
420f7cf202 system: clean up TestPlaceUnit() 2014-11-26 10:32:43 -08:00
Alex Crawford
624df676d0 config/unit: move Type() and Group() out of config 2014-11-26 10:32:43 -08:00
Alex Crawford
75ed8dacf9 initialize: clean up TestProcessUnits() 2014-11-26 10:32:43 -08:00
Alex Crawford
dcaabe4d4a system: clean up UnitManager interface 2014-11-26 10:32:43 -08:00
Alex Crawford
92c57423ba Merge pull request #269 from crawford/valid
validate: promote invalid values to an error
2014-11-26 10:32:27 -08:00
Alex Crawford
7447e133c9 validate: promote invalid values to an error 2014-11-26 10:29:09 -08:00
Eugene Yakubovich
4e466c12da Merge pull request #267 from thommay/flannel_unit
the flannel service is called flanneld
2014-11-25 12:30:58 -08:00
Thom May
333468dba3 the flannel service is called flanneld 2014-11-25 14:00:53 +00:00
Alex Crawford
55c3a793ad coreos-cloudinit: bump to 0.11.4+git 2014-11-21 20:11:54 -08:00
Alex Crawford
eca51031c8 coreos-cloudinit: bump to 0.11.4 2014-11-21 20:11:37 -08:00
Alex Crawford
19522bcb82 Merge pull request #266 from crawford/config
config: update configs to match etcd, fleet, and flannel
2014-11-21 20:10:34 -08:00
Alex Crawford
62248ea33d config/fleet: fix configs
Added EtcdKeyPrefix and fixed the types of EngineReconcileInterval and EtcdRequestTimeout.
2014-11-21 16:57:00 -08:00
Alex Crawford
d2a19cc86d config/flannel: correct - vs _ 2014-11-21 16:57:00 -08:00
Alex Crawford
08131ffab1 config/etcd: fix configs
This new table is pulled from the etcd codebase rather than the docs...

Added:
 GraphiteHost
 PeerElectionTimeout
 PeerHeartbeatInterval
 PeerKeyFile
 RetryInterval
 SnapshotCount
 StrTrace
 VeryVeryVerbose

Fixed types:
 ClusterActiveSize
 ClusterRemoveDelay
 ClusterSyncInterval
 HTTPReadTimeout
 HTTPWriteTimeout
 MaxResultBuffer
 MaxRetryAttempts
 Snapshot
 Verbose
 VeryVerbose

Renamed:
 Cors

Removed:
 MaxClusterSize
 CPUProfileFile
2014-11-21 16:57:00 -08:00
Alex Crawford
4a0019c669 config: add support for float64 2014-11-21 16:13:49 -08:00
Alex Crawford
3275ead1ec coreos-cloudinit: bump to 0.11.3+git 2014-11-21 12:25:26 -08:00
Alex Crawford
32b6a55724 coreos-cloudinit: bump to 0.11.3 2014-11-21 12:25:04 -08:00
Alex Crawford
6c43644369 Merge pull request #265 from crawford/update
config/update: add "off" as a valid strategy
2014-11-21 12:22:45 -08:00
Alex Crawford
e6593d49e6 config/update: add "off" as a valid strategy
It was assumed that the user would specify the reboot strategy as an
unquoted value. In the case that they turn off updates, `off` is
interpreted as a boolean and the normalization pass converts that to
`false`. In the event that the user uses `"off"`, it's interpreted as a
string and not modified.
2014-11-21 10:41:03 -08:00
Alex Crawford
ab752b239f coreos-cloudinit: bump to 0.11.2+git 2014-11-20 11:29:25 -08:00
Alex Crawford
0742e4d357 coreos-cloudinit: bump to 0.11.2 2014-11-20 11:29:12 -08:00
Alex Crawford
78f586ec9e Merge pull request #262 from crawford/permissions
config: fix parsing of file permissions
2014-11-20 11:28:11 -08:00
Alex Crawford
6f91b76d79 docs: correct type of permissions 2014-11-20 11:14:44 -08:00
Alex Crawford
5c80ccacc4 config: fix parsing of file permissions
The file permissions can be specified (unfortunately) as a string or an
octal integer. During the normalization step, every field is
unmarshalled into an interface{}. String types are kept in tact but
integers are converted to decimal integers. If the raw config
represented the permissions as an octal, it would be converted to
decimal _before_ it was saved to RawFilePermissions. Permissions() would
then try to convert it again, assuming it was an octal. The new behavior
doesn't assume the radix of the number, allowing decimal and octal
input.
2014-11-20 11:14:44 -08:00
Rob Szumski
44fdf95d99 docs: mention validate flag 2014-11-20 11:12:31 -08:00
Rob Szumski
0a62614eec docs: link to validator 2014-11-20 10:58:57 -08:00
Alex Crawford
97758b343b coreos-cloudinit: bump to 0.11.1+git 2014-11-18 12:14:34 -08:00
Alex Crawford
fb6f52b360 coreos-cloudinit: bump to 0.11.1 2014-11-18 12:14:29 -08:00
Alex Crawford
786cd2a539 Merge pull request #259 from crawford/hyphen
config/validate: disable - vs _ message for now
2014-11-18 12:12:26 -08:00
Alex Crawford
45793f1254 config/validate: disable - vs _ message for now 2014-11-18 12:11:50 -08:00
Alex Crawford
b621756d92 Merge pull request #258 from crawford/header
config/validate: fix line number for header check
2014-11-18 12:11:35 -08:00
Alex Crawford
a5b5c700a6 config/validate: fix line number for header check 2014-11-18 12:02:23 -08:00
Kiril Vladimirov
ea95920f31 fix(datasource/CloudSigma): Make sure DHCP has run 2014-11-17 15:35:10 +02:00
Alex Crawford
d7602f3c08 Merge pull request #244 from eyakubovich/master
flannel: added flannel support and helper to make dropins
2014-11-14 10:46:19 -08:00
Eugene Yakubovich
a20addd05e flannel: added flannel support and helper to make dropins
fleet, flannel, and etcd all generate dropins from config.
To reduce code duplication, factor out a helper to do that.
2014-11-14 10:45:23 -08:00
Alex Crawford
d9d89a6fa0 coreos-cloudinit: bump to 0.11.0+git 2014-11-14 10:42:00 -08:00
Alex Crawford
3c26376326 coreos-cloudinit: bump to 0.11.0 2014-11-14 10:41:47 -08:00
Alex Crawford
d3294bcb86 Merge pull request #254 from crawford/validator
config: add new validator
2014-11-12 17:40:16 -08:00
Alex Crawford
dda314b518 flags: add validate flag
This will allow the user to run a standalone validation.
2014-11-12 16:48:57 -08:00
Alex Crawford
055a3c339a config/validate: add new config validator
This validator is still experimental and is going to need new rules in the
future. This lays out the general framework.
2014-11-12 16:48:57 -08:00
Alex Crawford
51f37100a1 config: remove config validator 2014-11-07 10:18:08 -08:00
Alex Crawford
88e8265cd6 config: seperate AssertValid and AssertStructValid
Added an error structure to make it possible to get the specifics of the failure.
2014-11-07 10:14:34 -08:00
Alex Crawford
6e2db882e6 script: move Script into config package 2014-11-07 10:13:52 -08:00
Alex Crawford
3e2823df1b Merge pull request #256 from crawford/hyphen
config: deprecate - in favor of _ for key names
2014-11-03 14:54:23 -08:00
Alex Crawford
46cb51cf91 Merge pull request #257 from crawford/networkd
networkd: remove double-restart workaround
2014-11-03 14:25:38 -08:00
Alex Crawford
1a6cee5305 networkd: remove double-restart workaround
The kernel fixed the underlying issue in 763e0ec and e721f87.
2014-11-03 14:11:15 -08:00
Alex Crawford
d02aa18839 config: deprecate - in favor of _ for key names
In all of the YAML tags, - has been replaced with _. normalizeConfig() and
normalizeKeys() have also been added to perform the normalization of the input
cloud-config.

As part of the normalization process, falsey values are converted to "false".
The "off" update strategy is no exception and as a result the "off" update
strategy has been changed to "false".
2014-11-03 12:09:52 -08:00
Alex Crawford
e9bda98b54 Merge pull request #252 from crawford/vet
go vet
2014-10-23 12:03:01 -07:00
Alex Crawford
badc874b74 travis: install go vet 2014-10-23 11:47:24 -07:00
Alex Crawford
c9e8c887b8 test: run go vet 2014-10-23 11:46:40 -07:00
Alex Crawford
8be307de49 *: fix warnings from go vet 2014-10-23 11:46:08 -07:00
Alex Crawford
562c474275 system: embed config within EtcHosts and Update 2014-10-23 11:44:15 -07:00
Kiril Vladimirov
b6062f0644 fix(datasource/CloudSigma): Populate local IPv4 address properly 2014-10-23 15:03:23 +03:00
Kiril Vladimirov
c5fada6e69 fix(datasource/CloudSigma): Populate public IPv4 address properly 2014-10-23 13:21:49 +03:00
Jonathan Boulle
5c5834863b Merge pull request #250 from jonboulle/master
*: switch to Godeps
2014-10-20 12:09:04 -07:00
Jonathan Boulle
44f0a949c5 *: switch to Godeps 2014-10-20 12:04:03 -07:00
Jonathan Boulle
106c4e7a2c Merge pull request #249 from jonboulle/license_header
*: add license header to all source files
2014-10-17 15:42:20 -07:00
Jonathan Boulle
6c1ba590aa *: add license header to all source files 2014-10-17 15:36:22 -07:00
Alex Crawford
45da664c59 Merge pull request #246 from crawford/master
Add support for Azure
2014-10-12 21:37:34 -07:00
Alex Crawford
2a71551ef2 azure: add support for azure (via azure agent) 2014-10-11 09:19:47 -07:00
Alex Crawford
84e1cb3242 datasource/waagent: add support for WAAgent metadata 2014-10-11 09:19:47 -07:00
Jonathan Boulle
5214ead926 Merge pull request #245 from jonboulle/units
init: simplify CloudConfigUnit interface
2014-10-06 15:26:36 -07:00
Jonathan Boulle
e2c24c4cef init: simplify CloudConfigUnit interface 2014-10-06 15:14:29 -07:00
Alex Crawford
75e288c553 coreos-cloudinit: bump to 0.10.4+git 2014-09-24 19:25:55 -07:00
Alex Crawford
0785840fe3 coreos-cloudinit: bump to 0.10.4 2014-09-24 19:25:34 -07:00
Alex Crawford
c10bfc2f56 Merge pull request #240 from epankala/euca4_compat_fix
AWS: Eucalyptus 4.x compatibility fix
2014-09-24 10:55:39 -07:00
Janne Paenkaelae
2f954dcdc2 AWS: Eucalyptus 4.x compatibility fix
For Eucalyptus 4.0.1 requesting metadata seem to work differently as with EC2.

In Euca:
> curl http://169.254.169.254/2009-04-04
<?xml version="1.0"?><Response><Errors><Error><Code>404 Not Found</Code><Message>unknown</Message></Error></Errors><RequestID>unknown</RequestID></Response>core@localhost ~ $

> curl http://169.254.169.254/2009-04-04/
dynamic
meta-data
user-data

In AWS EC2
> curl http://169.254.169.254/2009-04-04
"" (zero bytes)

> curl http://169.254.169.254/2009-04-04/
dynamic
meta-data
user-data

As the isAvailable() function in metadata.go tests only for errorcode
it fails in Euca.
2014-09-24 20:33:29 +03:00
Alex Crawford
cdfc94f4e9 Merge pull request #234 from crawford/validate
config: explicitly specify fields and seperate config and application
2014-09-24 07:42:09 -07:00
Alex Crawford
18e2f98414 cloudconfig: refactor config
- Move CloudConfig into config package
- Add YAML tags to CloudConfig
2014-09-23 17:59:32 -07:00
Alex Crawford
4b472795c4 user: move User into config package
- Add YAML tags for the fields
2014-09-23 17:59:19 -07:00
Alex Crawford
85b8d804c8 file: refactor config
- Seperate the config from Permissions()
- Add YAML tags for the fields
2014-09-23 17:59:16 -07:00
Alex Crawford
1fbbaaec19 unit: refactor config
- Seperate the config from Destination()
- Add YAML tags for the fields
2014-09-23 17:58:32 -07:00
Alex Crawford
667dbd8fb7 update: refactor config
- Explicitly specify all of the valid options for Update
- Seperate the config from File() and Units()
- Add YAML tags for the fields
2014-09-23 17:57:43 -07:00
Alex Crawford
6730cb7227 oem: refactor the config
- Seperate the config from File()
- Add YAML tags for the fields
2014-09-23 16:08:23 -07:00
Alex Crawford
9454522033 fleet: refactor config
- Explicitly specify all of the valid options for fleet
- Seperate the config from Units()
- Add YAML tags for the fields
2014-09-23 16:07:53 -07:00
Alex Crawford
c255739a93 etcd: refactor config
- Explicitly specify all of the valid options for etcd
- Remove the default name generation (ETCD_NAME is set by its unit file now)
- Seperate the etcd config from Units()
- Remove support for DISCOVERY_URL
- Add YAML tags for the fields
2014-09-23 16:07:13 -07:00
Alex Crawford
2051cd3e1c Merge pull request #238 from crawford/docs
docs: fix documentation of coreos.units.command
2014-09-23 11:33:44 -07:00
Alex Crawford
b52cb3fea3 docs: fix documentation of coreos.units.command 2014-09-23 11:32:15 -07:00
Alex Crawford
da5f85b3fb coreos-cloudinit: bump to 0.10.3+git 2014-09-17 12:19:27 -07:00
Alex Crawford
9999178538 coreos-cloudinit: bump to 0.10.3 2014-09-17 12:19:13 -07:00
Alex Crawford
8f766e4666 Merge pull request #235 from crawford/routes
network: add support for CIDR addresses Debian routes
2014-09-17 12:18:16 -07:00
Alex Crawford
2d28d16c92 network: add support for CIDR addresses Debian routes
OnMetal is changing their template from:
`route add -net 1.2.3.0 netmask 255.255.255.0 gw 10.1.2.1 || true`
to:
`route add -net 1.2.3.0/24 gw 10.1.2.1 || true`
2014-09-16 17:36:34 -07:00
Alex Crawford
e9cd09dd7b coreos-cloudinit: bump to 0.10.2+git 2014-09-14 08:19:57 -07:00
Alex Crawford
8370b30aa2 coreos-cloudinit: bump to 0.10.2 2014-09-14 08:19:33 -07:00
Alex Crawford
3e015cc3a1 Merge pull request #233 from crawford/configdrive
configdrive: don't fail if no network config was provided
2014-09-14 08:18:14 -07:00
Alex Crawford
a0fe6d0884 configdrive: return an empty network config when filename is empty
Additionally, don't bother checking for a network config if it isn't going to
be processed.
2014-09-13 21:51:51 -07:00
Alex Crawford
585ce5fcd9 Revert "metadata: don't fail if no network config was provided"
This reverts commit c1f373e648.
2014-09-13 21:01:42 -07:00
Alex Crawford
72445796ca coreos-cloudinit: bump to 0.10.1+git 2014-09-12 16:48:15 -07:00
Alex Crawford
7342d91a85 coreos-cloudinit: bump to 0.10.1 2014-09-12 16:47:58 -07:00
Alex Crawford
db1bc51c98 Merge pull request #231 from crawford/netconf
metadata: don't fail if no network config was provided
2014-09-12 16:35:24 -07:00
Alex Crawford
c1f373e648 metadata: don't fail if no network config was provided 2014-09-12 16:29:27 -07:00
Alex Crawford
db49a16002 coreos-cloudinit: bump to 0.10.0+git 2014-09-11 17:37:05 -07:00
Alex Crawford
a4a6c281d9 coreos-cloudinit: bump to 0.10.0 2014-09-11 17:36:38 -07:00
Alex Crawford
17f8733121 Merge pull request #228 from crawford/sub
env: add support for escaping environment substitutions
2014-09-11 15:34:03 -07:00
Alex Crawford
7dec922618 env: add support for escaping environment substitutions 2014-09-11 15:30:33 -07:00
Alex Crawford
54d3ae27af Merge pull request #226 from crawford/oem
flags: add oem flag
2014-09-11 13:25:21 -07:00
Alex Crawford
ee2416af64 flags: move the flags into their own namespace 2014-09-11 12:00:17 -07:00
Alex Crawford
cda037f9a5 flags: add oem flag
The oem flag will allow each of the OEMs to specify one flag only, acting as a
shortcut to their specific configuration. This will allow us to update which
options each OEM uses when running cloudinit.
2014-09-11 12:00:17 -07:00
Alex Crawford
549806cf64 Merge pull request #227 from crawford/ipv6
metadata: add support for IPv6 variable substitution
2014-09-11 10:45:33 -07:00
Alex Crawford
56815a6756 metadata: add support for IPv6 variable substitution 2014-09-11 10:43:02 -07:00
Alex Crawford
24a6f7c49c Merge pull request #225 from crawford/exit
userdata: change handling of bad userdata
2014-09-10 19:16:12 -07:00
Alex Crawford
98484be434 userdata: change handling of bad userdata
Don't fail after encountering bad userdata. Continue processing the metadata
and then exit. This will allow people with bad userdata to actually log in and
see the error.
2014-09-10 17:50:23 -07:00
Jonathan Boulle
9024659296 Merge pull request #217 from ecnahc515/patch-1
Fix broken link to fleet config
2014-09-09 15:19:18 -07:00
Chance Zibolski
fc6940f7ba Documentation: More specific link to fleet config.
Add an anchor tag to the url to take person directly to config section.
2014-09-09 15:15:55 -07:00
Brian Waldon
f2fd95699b Merge pull request #224 from bcwaldon/typo
docs: fix a typo
2014-09-09 12:36:42 -07:00
bdevloed
65db96cc7c docs: fix a typo 2014-09-09 12:31:54 -07:00
Alex Crawford
c17b93b5c0 Merge pull request #223 from crawford/yaml
third_party: sync third_party/gopkg.in/yaml.v1
2014-09-08 19:28:59 -07:00
Alex Crawford
d352f8ce6a Merge pull request #222 from crawford/contribute
docs: Update maintainers and contribution guide
2014-09-08 15:54:30 -07:00
Alex Crawford
78aa2c56ec yaml: replace goyaml with yaml 2014-09-08 13:25:27 -07:00
Alex Crawford
c5b3788282 third_party: sync third_party/gopkg.in/yaml.v1
Update launchpad.net/goyaml to gopkg.in/yaml.v1
2014-09-08 13:23:50 -07:00
Alex Crawford
5e98970bb5 docs: Update maintainers and contribution guide 2014-09-08 12:55:17 -07:00
Alex Crawford
cbdd446c55 Merge pull request #220 from crawford/docs
docs: Update list of platforms supporting variable substitutions
2014-09-05 11:51:45 -07:00
Alex Crawford
316cadcf44 docs: Update list of platforms supporting variable substitutions 2014-09-04 12:57:19 -07:00
Alex Crawford
5a939be21b coreos-cloudinit: bump to 0.9.6+git 2014-09-02 17:49:09 -07:00
Alex Crawford
8d76c64386 coreos-cloudinit: bump to 0.9.6 2014-09-02 17:48:45 -07:00
Alex Crawford
1b854eb51e Merge pull request #218 from crawford/units
units: Ensure that the units are executed in order
2014-09-02 17:40:37 -07:00
Alex Crawford
9fcf338bf3 units: Ensure that the units are executed in order 2014-09-02 17:15:32 -07:00
Alex Crawford
fda72bdb5c coreos-cloudinit: bump to 0.9.5+git 2014-09-02 10:10:59 -07:00
Alex Crawford
685a38c6c8 coreos-cloudinit: bump to 0.9.5 2014-09-02 10:10:41 -07:00
Alex Crawford
9d15f2cfaf Merge pull request #213 from crawford/digitalocean
digitalocean: Add support for DigitalOcean
2014-09-01 16:55:12 -07:00
Alex Crawford
2134fce791 digitalocean: Add tests for network unit generation 2014-09-01 16:53:15 -07:00
Alex Crawford
3abd6b2225 digitalocean: Add DigitalOcean metadata service
Move debian-related processing into its own file.
2014-09-01 16:53:15 -07:00
Alex Crawford
2a8e6c9566 network: Fall back to MAC address if there is no name 2014-09-01 09:29:45 -07:00
Alex Crawford
abe43537da metadata: Merge the network config 2014-09-01 09:29:45 -07:00
Jonathan Boulle
3a550af651 Merge pull request #216 from robszumski/patch-2
docs: fix broken link to fleet docs
2014-08-29 11:22:13 -07:00
Rob Szumski
61c3a0eb2d docs: fix broken link to fleet docs 2014-08-29 11:17:05 -07:00
Brian Waldon
480176bc11 Merge pull request #214 from bcwaldon/clarify-write-files
doc: clarify docs around write_files
2014-08-28 20:24:11 -07:00
Brian Waldon
01b18eb551 squash: fix spacing 2014-08-28 13:48:58 -07:00
Brian Waldon
970ef435b6 doc: clarify docs around write_files 2014-08-28 13:33:59 -07:00
Alex Crawford
e8d0021140 Merge pull request #212 from crawford/metadata
refactor: Refactor metadata and datasources to be more testable
2014-08-26 18:45:10 -07:00
Alex Crawford
e9ec78ac6f test: Refactor interface tests a little 2014-08-26 13:18:46 -07:00
Alex Crawford
4a2e417781 network: Add support for multiple addresses and HW addresses
Logical Interfaces can be assigned a hardware address allowing them
to match on MAC address. The static config method also needs to
support specifying multiple addresses.
2014-08-26 13:07:38 -07:00
Alex Crawford
604ef7ecb4 datasource: Add FetchNetworkConfig
FetchNetworkConfig is currently only used by ConfigDrive to read the
network config file from the disk.
2014-08-26 13:04:43 -07:00
Alex Crawford
c39dd5cc67 networkd: Fix bug causing bonding to always be loaded 2014-08-26 13:04:21 -07:00
Alex Crawford
a923161f4a metadata: Refactor common parts out of ec2 2014-08-26 12:02:56 -07:00
Alex Crawford
e59e2f6cd5 Merge pull request #210 from crawford/test
test: Add gofmt to test
2014-08-25 17:04:04 -07:00
Alex Crawford
e90fe3eba8 test: Add gofmt to test 2014-08-25 12:48:52 -07:00
Alex Crawford
fb0187b197 gofmt: sort 2014-08-25 12:35:40 -07:00
Michael Marineau
6babe74716 Merge pull request #209 from marineam/go13
travis: enable testing under go 1.3
2014-08-25 12:26:23 -07:00
Michael Marineau
b1e88284ca travis: enable testing under go 1.3 2014-08-25 12:21:07 -07:00
Alex Crawford
18a65f7dac Merge pull request #208 from crawford/go
test: Fix tests for Go 1.3
2014-08-25 12:19:52 -07:00
Alex Crawford
0c212c72c9 test: Fix tests for Go 1.3 2014-08-25 12:01:27 -07:00
Alex Crawford
6a800d8cc0 coreos-cloudinit: bump to 0.9.4+git 2014-08-24 18:41:20 -07:00
Alex Crawford
5e112147bb coreos-cloudinit: bump to 0.9.4 2014-08-24 18:40:53 -07:00
Alex Crawford
7e78b1563f Merge pull request #206 from crawford/tests
test: Enable tests for CloudSigma datasource
2014-08-24 18:36:38 -07:00
Alex Crawford
ecbe81f103 test: Enable tests for CloudSigma datasource 2014-08-24 17:08:49 -07:00
Alex Crawford
45c20c1dd3 Merge pull request #196 from Vladimiroff/cloudsigma
cloudsigma: Add support for CloudSigma datasource
2014-08-15 15:21:33 -07:00
Alex Crawford
8ce925a060 coreos-cloudinit: bump to 0.9.3+git 2014-08-15 10:47:28 -07:00
Alex Crawford
eadb6ef42c coreos-cloudinit: bump to 0.9.3 2014-08-15 10:46:46 -07:00
Alex Crawford
7518f0ec93 Merge pull request #204 from crawford/configdrive
configdrive: Remove broken support for ec2 metadata
2014-08-15 10:43:26 -07:00
Alex Crawford
f0b9eaf2fe configdrive: Remove broken support for ec2 metadata
As it turns out, certain metadata is only present in the ec2 flavor
of metadata (e.g. public_ipv4) and other data is only present in
the openstack flavor (e.g. network_config). For now, just read the
openstack metadata.
2014-08-15 10:35:21 -07:00
Kiril Vladimirov
7320a2cbf2 feat(datasource/metadata): Add datasource for CloudSigma 2014-08-15 12:08:55 +03:00
Kiril Vladimirov
57950b3ed9 add(goserial): import github.com/tarm/goserial 2014-08-15 12:08:34 +03:00
Kiril Vladimirov
85c6a2a16a add(cepgo): import github.com/cloudsigma/cepgo 2014-08-15 12:07:58 +03:00
Jonathan Boulle
24b44e86a6 coreos-cloudinit: bump to 0.9.2+git 2014-08-12 11:38:51 -07:00
Jonathan Boulle
2f52ad4ef8 coreos-cloudinit: bump to 0.9.2 2014-08-12 11:38:12 -07:00
Jonathan Boulle
735d6c6161 Merge pull request #202 from jonboulle/env
environment: write new keys in consistent order
2014-08-11 22:40:42 -07:00
Alex Crawford
1cf275bad6 Merge pull request #201 from crawford/configdrive
configdrive: fix root path
2014-08-11 20:11:17 -07:00
Jonathan Boulle
f1c97cb4d5 environment: write new keys in consistent order 2014-08-11 18:24:58 -07:00
Alex Crawford
d143904aa9 configdrive: fix root path 2014-08-11 17:57:10 -07:00
Jonathan Boulle
c428ce2cc5 Merge pull request #200 from jonboulle/fu
initialize: use correct heuristic to check if etcdenvironment is set
2014-08-11 17:44:44 -07:00
Jonathan Boulle
dfb5b4fc3a initialize: use correct heuristic to check if etcdenvironment is set
In some circumstances (e.g. nova-agent-watcher) cloudconfig files will
be created where the EtcdEnvironment is an empty map, and hence != nil.
If this is the case we should not do anything at all (because the user
hasn't explicitly asked us to configure etcd). This change standardises
behaviour with the check that we already do for FleetEnvironment.
2014-08-11 16:01:08 -07:00
Alex Crawford
97d5538533 Merge pull request #197 from crawford/ec2
datasource: Fix ec2 URLs
2014-08-06 22:45:03 -07:00
Alex Crawford
6b8f82b5d3 datasource: Fix ec2 URLs
_ vs -
2014-08-06 21:31:43 -07:00
Alex Crawford
facde6609f Merge pull request #194 from crawford/metadata
datasource: Refactoring datasources
2014-08-06 15:55:13 -07:00
Alex Crawford
d68ae84b37 metadata: Refactor metadata service into ec2 metadata
Added more testing.
2014-08-05 17:19:43 -07:00
Alex Crawford
54aa39543b timeouts: Use After() instead of Tick() 2014-08-04 15:10:14 -07:00
Alex Crawford
8566a2c118 datasource: Move datasources into their own packages. 2014-08-04 15:10:07 -07:00
Alex Crawford
49ac083af5 coreos-cloudinit: bump to 0.9.1+git 2014-08-04 14:14:24 -07:00
Alex Crawford
5d65ca230a coreos-cloudinit: bump to 0.9.1 2014-08-04 14:13:51 -07:00
Alex Crawford
38b3e1213a Merge pull request #188 from crawford/configdrive
configdrive: Use the EC2 metadata over OpenStack
2014-08-04 11:12:06 -07:00
Alex Crawford
4eedca26e9 configdrive: Use the EC2 metadata over OpenStack
Standardize on specific EC2 and OpenStack versions and add tests.
2014-08-04 10:18:29 -07:00
Brian Waldon
f2b342c8be doc: escape user.home example 2014-08-01 13:20:44 -07:00
Michael Marineau
c19d8f6b61 Merge pull request #193 from benjic/cloudconfig_variables
docs(quick-start): Clarified use of fields in cloud config
2014-07-24 11:02:03 -07:00
Benjamin Campbell
7913f74351 docs(quick-start) Enumerated supported platforms
Following suggestion a list of platforms that *do* support cloud config variables. In addition minor mark up formatting is added.
2014-07-24 11:54:31 -06:00
Benjamin Campbell
5593408be8 docs(quick-start): Clarified use of fields in cloud config
Updated the language to illustrate that fields in a cloud config is not
supported in all environments. This is expressed explicitly in PXE and
install to disk pages. The quick start lacked this information and is
inconsistent.
2014-07-24 11:27:35 -06:00
Alex Crawford
7fc67c2acf Merge pull request #191 from crawford/panic
config: Verify that type assertions are valid
2014-07-22 11:51:39 -07:00
Alex Crawford
b093094292 config: Verify that type assertions are valid 2014-07-22 11:39:20 -07:00
Michael Marineau
9a80fd714a Merge pull request #181 from robszumski/docs-startup
fix(docs): clarity around boot behavior and unit usage
2014-07-21 22:12:19 -07:00
Rob Szumski
fef5473881 fix(docs): clarity around boot behavior and unit usage 2014-07-21 21:41:00 -07:00
Alex Crawford
bf5a2b208f coreos-cloudinit: bump to 0.9.0+git 2014-07-21 19:17:14 -07:00
Alex Crawford
364507fb75 coreos-cloudinit: bump to 0.9.0 2014-07-21 19:16:11 -07:00
Alex Crawford
08d4842502 Merge pull request #190 from crawford/logs
Logs
2014-07-21 12:22:41 -07:00
Alex Crawford
21e32e44f8 system: Add more logging for networkd 2014-07-21 11:25:22 -07:00
Alex Crawford
7a06dee16f system: Cleanup redundant code 2014-07-21 11:24:42 -07:00
Alex Crawford
ff9cf5743d Merge pull request #187 from crawford/order
networkd: Reverse lexicographic order of generated unit files
2014-07-18 13:23:58 -07:00
Alex Crawford
1b10a3a187 networkd: Reverse lexicographic order of generated unit files 2014-07-17 20:47:37 -07:00
Michael Marineau
10838e001d Merge pull request #186 from robszumski/add-highlighting
feat(docs): add syntax highlighting
2014-07-15 15:26:33 -07:00
Rob Szumski
96370ac5b9 feat(docs): add syntax highlighting 2014-07-14 16:16:14 -07:00
Michael Marineau
0b82cd074d Merge pull request #180 from marineam/systemd_testing
chore(*): split out unit processing from config.Apply
2014-07-11 20:09:08 -07:00
Alex Crawford
a974e85103 Merge pull request #174 from crawford/teeth
networkd: Fix issues with bonding and VLANs
2014-07-11 15:48:02 -07:00
Michael Marineau
f0450662b0 Merge pull request #183 from marineam/fix
tests: fix error messages, use Fatalf
2014-07-11 15:40:54 -07:00
Michael Marineau
03e29d1291 tests: fix error messages, use Fatalf 2014-07-11 15:38:04 -07:00
Michael Marineau
98ae5d88aa coreos-cloudinit: bump to 0.8.9+git 2014-07-11 14:40:57 -07:00
Michael Marineau
bf5d3539c9 coreos-cloudinit: bump to 0.8.9 2014-07-11 14:40:34 -07:00
Michael Marineau
5e4cbcd909 Merge pull request #182 from marineam/fix
env_file: fix broken test cases
2014-07-11 14:38:56 -07:00
Michael Marineau
a270c4c737 env_file: fix broken test cases
TestWriteEnvFileDos2Unix had a copy/paste bug, it shouldn't have
asserted that mtime doesn't change because the file is actually being
modified in this test. This didn't come up earlier because the actual
comparison wasn't using Time.Equal as it should have.

Instead switch to comparing inode numbers which is the actual thing I
wanted to test for in the first place, just accessing them is much more
awkard. Now all tests where it is relevant check the inode in addition
to the contents.
2014-07-11 13:35:10 -07:00
Michael Marineau
f356a8a690 coreos-cloudinit: bump to 0.8.8+git 2014-07-11 11:13:01 -07:00
Michael Marineau
b1a897d75c coreos-cloudinit: bump to 0.8.8 2014-07-11 11:12:15 -07:00
Jonathan Boulle
be51f4eba0 chore(*): split out unit processing from config.Apply 2014-07-11 10:44:19 -07:00
Michael Marineau
a55e2cd49b Merge pull request #178 from marineam/env
Write /etc/environment
2014-07-11 10:39:33 -07:00
Michael Marineau
983501e43b environment: add support for updating /etc/environment with IP values
To maintain the behavior of the coreos-setup-environment that has
started to move into cloudinit we need to write out /etc/environment
with the public and private addresses, if known. The file is updated so
that other contents are not replaced. This behavior is disabled entirely
if /etc/environment was written by a write_files entry.
2014-07-11 10:34:44 -07:00
Alex Crawford
e3037f18a6 networkd: Restart networkd twice to work around race
https://bugs.freedesktop.org/show_bug.cgi?id=76077
2014-07-10 23:40:42 -07:00
Alex Crawford
fe388a3ab6 networkd: Create config directory before writing config 2014-07-10 23:40:42 -07:00
Alex Crawford
c820f2b1cf bonding: Add support for probing the bonding module with parameters
Until support for bonding params is added to networkd, this will be
neccessary in order to use bonding parameters (i.e. miimon, mode).
This also makes it such that the 8012q module will only be loaded if
the network config makes use of VLANs.
2014-07-10 23:40:42 -07:00
Michael Marineau
81824be3bf system: new file writer for updating env-style files
This can be used to safely update config files cloudinit does not have
exclusive control over. For example update.conf or /etc/environment.
2014-07-10 15:53:32 -07:00
Michael Marineau
98c26440be Merge pull request #176 from jayofdoom/master
Document need for #cloud-config in cloud-config.yml
2014-07-09 16:41:00 -07:00
Jay Faulkner
3b5fcc393b Document need for #cloud-config in cloud-config.yml
- cloud-config.yml does not work if it's missing the #cloud-config
  directive at the top. This is undocumented, except in the examples.
2014-07-09 16:36:11 -07:00
Alex Crawford
9528077340 coreos-cloudinit: bump to 0.8.7+git 2014-07-02 15:20:45 -07:00
Alex Crawford
4355a05d55 coreos-cloudinit: bump to 0.8.7 2014-07-02 15:20:26 -07:00
Alex Crawford
52c44923dd Merge pull request #173 from crawford/metadata
metadata-service: remove check for OpenStack meta_data.json
2014-07-02 15:19:37 -07:00
Alex Crawford
47748ef4b6 metadata-service: remove check for OpenStack meta_data.json
The meta_data.json blob under OpenStack doesn't actually contain all
of the metadata... Fall back to explicitly requesting each attribute.
2014-07-02 14:38:23 -07:00
Alex Crawford
8eca10200e coreos-cloudinit: bump to 0.8.6+git 2014-07-01 16:17:00 -07:00
Alex Crawford
43be8c8996 coreos-cloudinit: bump to 0.8.6 2014-07-01 16:16:41 -07:00
Alex Crawford
19b4b1160e Merge pull request #171 from crawford/err
metadata-service: Handle no user-data
2014-07-01 16:15:32 -07:00
Alex Crawford
ce6fccfb3c metadata-service: Handle no user-data 2014-07-01 16:10:18 -07:00
Alex Crawford
7d89aefb82 coreos-cloudinit: bump to 0.8.5+git 2014-07-01 15:45:49 -07:00
Alex Crawford
2369e2a920 coreos-cloudinit: bump to 0.8.5 2014-07-01 15:45:23 -07:00
Alex Crawford
6d808048d3 Merge pull request #170 from crawford/metadata
metadata: Fetch the public and private IP addresses
2014-07-01 15:44:14 -07:00
Alex Crawford
276f0b5d99 metadata: Fetch the public and private IP addresses 2014-07-01 14:43:19 -07:00
Jonathan Boulle
92bd5ca5d4 coreos-cloudinit: bump to 0.8.4+git 2014-07-01 12:16:09 -07:00
Jonathan Boulle
5b5ffea126 coreos-cloudinit: bump to 0.8.4 2014-07-01 12:15:48 -07:00
Jonathan Boulle
18068e9375 Merge pull request #169 from jonboulle/pebkac
coreos-cloudinit: apply environment to userdata string
2014-07-01 12:15:06 -07:00
Jonathan Boulle
1b3cabb035 coreos-cloudinit: apply environment to userdata string 2014-07-01 12:08:42 -07:00
Jonathan Boulle
1be2bec1c2 coreos-cloudinit: bump to 0.8.3+git 2014-06-30 22:12:13 -07:00
Jonathan Boulle
f3bd5f543e coreos-cloudinit: bump to 0.8.3 2014-06-30 22:11:15 -07:00
Jonathan Boulle
660feb59b9 Merge pull request #168 from jonboulle/foo
fix ordering error in mergeCloudConfig
2014-06-30 22:08:47 -07:00
Jonathan Boulle
9673dbe12b coreos-cloudinit: fix ordering error in merge invocation 2014-06-30 22:07:05 -07:00
Alex Crawford
2be435dd83 coreos-cloudinit: bump to 0.8.2+git 2014-06-30 18:11:14 -07:00
Alex Crawford
2d91369596 coreos-cloudinit: bump to 0.8.2 2014-06-30 18:10:20 -07:00
Alex Crawford
d8d3928978 Merge pull request #167 from crawford/sshkeys
metadata-service: fix ssh key retrieval and application
2014-06-30 18:08:04 -07:00
Alex Crawford
7fcc540154 metadata-service: fix ssh key retrieval and application
The metadata service wasn't properly fetching the ssh keys from metadata.
Drop the key traversal in favor of explict key urls.
2014-06-30 17:45:08 -07:00
Jonathan Boulle
cb7fbd4668 Merge pull request #166 from jonboulle/merge
cloudinit: merge cloudconfig info from user-data and meta-data
2014-06-30 11:27:47 -07:00
Jonathan Boulle
d4e048a1f4 ParseUserData: return nil on empty input string 2014-06-30 11:27:33 -07:00
Jonathan Boulle
231c0fa20b initialize: add tests for ParseMetadata 2014-06-27 23:53:06 -07:00
Jonathan Boulle
1aabacc769 cloudinit: merge cloudconfig info from user-data and meta-data
This attempts to retrieve cloudconfigs from two sources: the meta-data
service, and the user-data service. If only one cloudconfig is found,
that is applied to the system. If both services return a cloudconfig,
the two are merged into a single cloudconfig which is then applied to
the system.

Only a subset of parameters are merged (because the meta-data service
currently only partially populates a cloudconfig). In the event of any
conflicts, parameters in the user-data cloudconfig take precedence over
those in the meta-data cloudconfig.
2014-06-27 23:48:48 -07:00
Alex Crawford
6a2927d701 coreos-cloudinit: bump to 0.8.1+git 2014-06-27 15:00:05 -07:00
Alex Crawford
126188510b coreos-cloudinit: bump to 0.8.1 2014-06-27 14:59:56 -07:00
Alex Crawford
4627ccb444 Merge pull request #165 from crawford/units
units: update dependencies
2014-06-27 14:55:48 -07:00
Alex Crawford
aff372111a units: update dependencies 2014-06-27 14:29:59 -07:00
Alex Crawford
c7081b9918 coreos-cloudinit: bump to 0.8.0+git 2014-06-27 11:33:56 -07:00
Alex Crawford
9ba3b18b59 coreos-cloudinit: bump to 0.8.0 2014-06-27 11:32:52 -07:00
Alex Crawford
099de62e9a Merge pull request #164 from crawford/datasources
datasources: Add support for specifying multiple datasources
2014-06-27 00:25:09 -07:00
Alex Crawford
c089216cb5 datasources: Add support for specifying multiple datasources
If multiple sources are specified, the first available source is used.
2014-06-26 22:32:39 -07:00
Alex Crawford
68dc902ed1 HttpClient: Refactor timeout into two seperate functions 2014-06-26 15:16:22 -07:00
Jonathan Boulle
ad66b1c92f Merge pull request #163 from jonboulle/net
coreos-cloudinit: restrict convert-netconf to configdrive
2014-06-25 14:35:27 -07:00
Jonathan Boulle
fbdece2762 coreos-cloudinit: restrict convert-netconf to configdrive 2014-06-25 14:28:11 -07:00
Jonathan Boulle
f85eafb7ca Merge pull request #162 from jonboulle/fffffffffffffffffff
initialize/env: handle nil substitution maps properly
2014-06-25 12:10:00 -07:00
Jonathan Boulle
f0dba2294e initialize/env: handle nil substitution maps properly 2014-06-25 12:07:48 -07:00
Alex Crawford
bda3948382 Merge pull request #159 from crawford/metadata
metadataService: Check both ec2 and openstack urls more explicitly
2014-06-25 11:26:19 -07:00
Alex Crawford
fae81c78f3 metadataService: Check both ec2 and openstack urls more explicitly
Remove the root url parameter for -from-metadata-service since this
is a guarenteed value. Additionally, check for both ec2 and openstack
urls for the metadata and userdata. Fix a bug with the -from-url
option and a panic on an empty response.
2014-06-25 11:19:11 -07:00
Alex Crawford
a5dec7d7bd cloudconfig: Process metadata before userdata
This gives the options in userdata a higher precedence over metadata.
2014-06-25 10:35:26 -07:00
Jonathan Boulle
e1222c9885 Merge pull request #161 from jonboulle/doc
metadata: add links to metadata source information
2014-06-25 08:55:26 -07:00
Jonathan Boulle
ded3bcf122 metadata: add links to metadata source information 2014-06-24 19:26:07 -07:00
Jonathan Boulle
80d00cde94 Merge pull request #158 from jonboulle/nettttt
cloudinit: retrieve IPv4 addresses from metadata
2014-06-24 19:11:15 -07:00
Jonathan Boulle
2805d70ece initialize/env: add notes about tests 2014-06-24 18:52:08 -07:00
Jonathan Boulle
439b7e8b98 initialize/env: fall back to COREOS_*_IPV4 env variables 2014-06-24 18:49:49 -07:00
Jonathan Boulle
ba1c1e97d0 cloudinit: retrieve IPv4 addresses from metadata
This uses the new MetadataService implementation to retrieve values for
$private_ipv4 and $public_ipv4 substitutions, instead of using
environment variables.
2014-06-24 17:46:06 -07:00
Alex Crawford
8a50fd8595 Merge pull request #154 from crawford/metadata
metadata-service: Add new datasource to download from metadata service
2014-06-24 15:18:27 -07:00
Alex Crawford
465bcce72c metadata_service: Add tests for constructing metadata 2014-06-24 15:08:03 -07:00
Alex Crawford
361edeebc6 metadata-service: Add metadata-service datasource
Move the old metadata-service datasource to url datasource. This new datasource
checks for the existance of meta-data.json and if it doesn't exist, walks the
meta-data directory to build a metadata blob.
2014-06-24 15:08:03 -07:00
Jonathan Boulle
29a7b0e34f Merge pull request #155 from jonboulle/etcd
etcdenvironment: order map keys consistently
2014-06-24 15:02:04 -07:00
Alex Crawford
8496ffb53a HttpClient: Wrap errors with error classes 2014-06-24 15:01:31 -07:00
Jonathan Boulle
2c717a6cd1 Merge pull request #157 from jonboulle/core
coreos-cloudinit: clean up flag handling
2014-06-24 14:57:18 -07:00
Jonathan Boulle
13a91c9181 coreos-cloudinit: clean up flag handling 2014-06-24 14:19:55 -07:00
Jonathan Boulle
338e1b64ab etcdenvironment: order map keys consistently 2014-06-23 15:13:11 -07:00
Alex Crawford
8eb0636034 Merge pull request #149 from crawford/network
feat(network): Add support for blind interfaces, support for hwaddress, and bug fixes
2014-06-20 17:53:37 -07:00
Alex Crawford
f7c25a1b83 doc(debian-interfaces): Add basic docs for convert-netconf 2014-06-20 17:51:57 -07:00
Alex Crawford
d6a0d0908c fix(network): Generate prefixes to ensure proper lexicographical ordering
In order for networkd to properly configure the network interfaces, the configs must be
prefixed to ensure that they load in the correct order (parent interfaces have a lower
prefix than their children).
2014-06-20 17:51:57 -07:00
Alex Crawford
5c89afc18a Merge pull request #152 from crawford/metadata
feat(meta_data): Add partial support for meta_data.json
2014-06-20 17:47:08 -07:00
Michael Marineau
376cc4bcac chore(coreos-cloudinit): bump to 0.7.7+git 2014-06-18 15:01:13 -07:00
Michael Marineau
d0a6d6f92f chore(coreos-cloudinit): bump to 0.7.7 2014-06-18 14:55:38 -07:00
Michael Marineau
2be1e52f32 Merge pull request #151 from marineam/mount
fix(configdrive): Use mount units, give virtfs a new mount point.
2014-06-18 13:51:11 -07:00
Michael Marineau
784a71e2bf fix(configdrive): Use mount units, give virtfs a new mount point.
Currently systemd cannot track dependencies on configdrive very well
because it is mounted via a service instead of a mount unit. Also since
the interaction between path and mount units can lead to unexpected
behavior if something goes wrong the cloudinit service is now triggered
explicitly by the mount again. The configdrive path unit remains only as
a fall back for containers where the mount unit doesn't kick in. Better
to have two mechanisms that trigger the cloudinit service than none. :)

Since mounting a virtfs based configdrive requires different mount
options and two different mount units cannot refer to the same path the
virtfs version now mounts to /media/configvirtfs.

There are also two new kernel options:
- `coreos.configdrive=1`: enable config drive on physical hardware.
- `coreos.configdrive=0`: disable config drive on virtual machines.
2014-06-18 13:01:19 -07:00
Alex Crawford
e6cf83a2e5 refactor(netconf): Move netconf processing and handle metadata 2014-06-18 12:43:41 -07:00
Alex Crawford
840c208b60 feat(metadata): Distinguish between userdata and metadata for datasources 2014-06-18 12:34:31 -07:00
Alex Crawford
29ed6b38bd refactor(env): Add the config root and netconf type to datasource and env 2014-06-18 12:27:15 -07:00
Alex Crawford
259c7e1fe2 fix(sshKeyName): Use the SSH key name provided 2014-06-18 11:47:17 -07:00
Alex Crawford
033c8d352f feat(network): Add support for hwaddress
Currently only supports the ether mode of hwaddress. No immediate plans
to support ax25, ARCnet, or netrom.
2014-06-14 21:30:14 -07:00
Alex Crawford
16d7e8af48 fix(network): Take down all interfaces properly
The map of interfaces wasn't being populated correctly. Also, clean up some prints.
2014-06-13 20:53:59 -07:00
Alex Crawford
159f4a2c7c feat(network): Add support for blind interfaces
It is valid for an interface to reference another, otherwise undeclared,
interface (i.e. a bond enslaves eth0 without eth0 having its own iface stanza).
In order to associate the two interfaces, the undeclared interface needs to be
implicitly created so that it can be referenced by the other. This adds the
capability to forward-declare interfaces in addition to cleaning up the
process a little bit.
2014-06-11 22:07:33 -07:00
Michael Marineau
160668284c chore(coreos-cloudinit): bump to 0.7.6+git 2014-06-07 16:04:33 -04:00
Michael Marineau
41b9dfcb1c chore(coreos-cloudinit): bump to 0.7.6 2014-06-07 16:01:31 -04:00
Michael Marineau
ef4c3483b6 Merge pull request #146 from marineam/fix
fix(update): Fix restart of update-engine
2014-06-07 13:04:49 -07:00
Michael Marineau
4bdf633075 fix(update): Fix restart of update-engine
The name was missing .service.
2014-06-07 12:08:22 -07:00
Brian Waldon
c9fc718e18 Merge pull request #145 from bcwaldon/drop-group-req
Relax requirements of update group value
2014-06-06 11:43:22 -07:00
Brian Waldon
4461b3d33d fix(update): Relax requirements of update group value 2014-06-06 11:29:09 -07:00
Jonathan Boulle
c6a1412f6b chore(coreos-cloudinit): bump to 0.7.5+git 2014-06-06 11:14:39 -07:00
308 changed files with 29526 additions and 4415 deletions

View File

@@ -1,8 +1,12 @@
language: go
go: 1.2
install:
- go get code.google.com/p/go.tools/cmd/cover
sudo: false
matrix:
include:
- go: 1.4
install:
- go get golang.org/x/tools/cmd/cover
- go get golang.org/x/tools/cmd/vet
- go: 1.5
script:
- ./test
- ./test

View File

@@ -39,22 +39,25 @@ Thanks for your contributions!
### Format of the Commit Message
We follow a rough convention for commit messages borrowed from AngularJS. This
is an example of a commit:
We follow a rough convention for commit messages that is designed to answer two
questions: what changed and why. The subject line should feature the what and
the body of the commit should describe the why.
```
feat(scripts/test-cluster): add a cluster test command
environment: write new keys in consistent order
this uses tmux to setup a test cluster that you can easily kill and
start for debugging.
Go 1.3 randomizes the ordering of keys when iterating over a map.
Sort the keys to make this ordering consistent.
Fixes #38
```
The format can be described more formally as follows:
```
<type>(<scope>): <subject>
<subsystem>: <what changed>
<BLANK LINE>
<body>
<why this change was made>
<BLANK LINE>
<footer>
```
@@ -63,25 +66,3 @@ The first line is the subject and should be no longer than 70 characters, the
second line is always blank, and other lines should be wrapped at 80 characters.
This allows the message to be easier to read on GitHub as well as in various
git tools.
#### Subject Line
The subject line contains a succinct description of the change.
#### Allowed `<type>`s
- *feat* (feature)
- *fix* (bug fix)
- *docs* (documentation)
- *style* (formatting, missing semi colons, …)
- *refactor*
- *test* (when adding missing tests)
- *chore* (maintain)
#### Allowed `<scope>`s
Scopes can anything specifying the place of the commit change in the code base -
for example, "api", "store", etc.
For more details on the commit format, see the [AngularJS commit style
guide](https://docs.google.com/a/coreos.com/document/d/1QrDFcIiPjSLDn3EL15IJygNPiHORgU1_OOAqWjiDU5Y/edit#).

View File

@@ -0,0 +1,38 @@
# Deprecated Cloud-Config Features
## Retrieving SSH Authorized Keys
### From a GitHub User
Using the `coreos-ssh-import-github` field, we can import public SSH keys from a GitHub user to use as authorized keys to a server.
```yaml
#cloud-config
users:
- name: elroy
coreos-ssh-import-github: elroy
```
### From an HTTP Endpoint
We can also pull public SSH keys from any HTTP endpoint which matches [GitHub's API response format](https://developer.github.com/v3/users/keys/#list-public-keys-for-a-user).
For example, if you have an installation of GitHub Enterprise, you can provide a complete URL with an authentication token:
```yaml
#cloud-config
users:
- name: elroy
coreos-ssh-import-url: https://github-enterprise.example.com/api/v3/users/elroy/keys?access_token=<TOKEN>
```
You can also specify any URL whose response matches the JSON format for public keys:
```yaml
#cloud-config
users:
- name: elroy
coreos-ssh-import-url: https://example.com/public-keys
```

View File

@@ -0,0 +1,26 @@
# Cloud-Config Locations
On every boot, coreos-cloudinit looks for a config file to configure your host. Here is a list of locations which are used by the Cloud-Config utility, depending on your CoreOS platform:
Location | Description
--- | --- | ---
|`/media/configvirtfs/openstack/latest/user_data`|`/media/configvirtfs` mount point with [config-2](/os/docs/latest/config-drive.html#contents-and-format) label. It should contain a `openstack/latest/user_data` relative path. Usually used by cloud providers or in VM installations.|
|`/media/configdrive/openstack/latest/user_data`|FAT or ISO9660 filesystem with [config-2](/os/docs/latest/config-drive.html#qemu-virtfs) label and `/media/configdrive/` mount point. It should also contain a `openstack/latest/user_data` relative path. Usually used in installations which are configured by USB Flash sticks or CDROM media.|
|Kernel command line: `cloud-config-url=http://example.com/user_data`.| You can find this string using this command `cat /proc/cmdline`. Usually used in [PXE](/os/docs/latest/booting-with-pxe.html) or [iPXE](/os/docs/latest/booting-with-ipxe.html) boots.|
|`/var/lib/coreos-install/user_data`| When you install CoreOS manually using the [coreos-install](/os/docs/latest/installing-to-disk.html) tool. Usually used in bare metal installations.|
|`/usr/share/oem/cloud-config.yml`| Path for OEM images.|
|`/var/lib/coreos-vagrant/vagrantfile-user-data`| Vagrant OEM scripts automatically store Cloud-Config into this path. |
|`/var/lib/waagent/CustomData`| Azure platform uses OEM path for first Cloud-Config initialization and then `/var/lib/waagent/CustomData` to apply your settings.|
|`http://169.254.169.254/metadata/v1/user-data` `http://169.254.169.254/2009-04-04/user-data` `https://metadata.packet.net/userdata`|DigitalOcean, EC2 and Packet cloud providers correspondingly use these URLs to download Cloud-Config.|
|`/usr/share/oem/bin/vmtoolsd --cmd "info-get guestinfo.coreos.config.data"`|Cloud-Config provided by [VMware Guestinfo][VMware Guestinfo]|
|`/usr/share/oem/bin/vmtoolsd --cmd "info-get guestinfo.coreos.config.url"`|Cloud-Config URL provided by [VMware Guestinfo][VMware Guestinfo]|
[VMware Guestinfo]: vmware-guestinfo.md
You can also run the `coreos-cloudinit` tool manually and provide a path to your custom Cloud-Config file:
```sh
sudo coreos-cloudinit --from-file=/home/core/cloud-config.yaml
```
This command will apply your custom cloud-config.

View File

@@ -13,20 +13,20 @@ If no **id** field is provided, coreos-cloudinit will ignore this section.
For example, the following cloud-config document...
```
```yaml
#cloud-config
coreos:
oem:
id: rackspace
name: Rackspace Cloud Servers
version-id: 168.0.0
home-url: https://www.rackspace.com/cloud/servers/
bug-report-url: https://github.com/coreos/coreos-overlay
id: "rackspace"
name: "Rackspace Cloud Servers"
version-id: "168.0.0"
home-url: "https://www.rackspace.com/cloud/servers/"
bug-report-url: "https://github.com/coreos/coreos-overlay"
```
...would be rendered to the following `/etc/oem-release`:
```
```yaml
ID=rackspace
NAME="Rackspace Cloud Servers"
VERSION_ID=168.0.0

View File

@@ -1,10 +1,20 @@
# Using Cloud-Config
CoreOS allows you to declaratively customize various OS-level items, such as network configuration, user accounts, and systemd units. This document describes the full list of items we can configure. The `coreos-cloudinit` program uses these files as it configures the OS after startup or during runtime.
CoreOS allows you to declaratively customize various OS-level items, such as network configuration, user accounts, and systemd units. This document describes the full list of items we can configure. The `coreos-cloudinit` program uses these files as it configures the OS after startup or during runtime.
Your cloud-config is processed during each boot. Invalid cloud-config won't be processed but will be logged in the journal. You can validate your cloud-config with the [CoreOS validator]({{site.url}}/validate) or by running `coreos-cloudinit -validate`.
In addition to `coreos-cloudinit -validate` command and https://coreos.com/validate/ online service you can debug `coreos-cloudinit` system output through the `journalctl` tool:
```sh
journalctl _EXE=/usr/bin/coreos-cloudinit
```
It will show `coreos-cloudinit` run output which was triggered by system boot.
## Configuration File
The file used by this system initialization program is called a "cloud-config" file. It is inspired by the [cloud-init][cloud-init] project's [cloud-config][cloud-config] file. which is "the defacto multi-distribution package that handles early initialization of a cloud instance" ([cloud-init docs][cloud-init-docs]). Because the cloud-init project includes tools which aren't used by CoreOS, only the relevant subset of its configuration items will be implemented in our cloud-config file. In addition to those, we added a few CoreOS-specific items, such as etcd configuration, OEM definition, and systemd units.
The file used by this system initialization program is called a "cloud-config" file. It is inspired by the [cloud-init][cloud-init] project's [cloud-config][cloud-config] file, which is "the defacto multi-distribution package that handles early initialization of a cloud instance" ([cloud-init docs][cloud-init-docs]). Because the cloud-init project includes tools which aren't used by CoreOS, only the relevant subset of its configuration items will be implemented in our cloud-config file. In addition to those, we added a few CoreOS-specific items, such as etcd configuration, OEM definition, and systemd units.
We've designed our implementation to allow the same cloud-config file to work across all of our supported platforms.
@@ -16,7 +26,7 @@ We've designed our implementation to allow the same cloud-config file to work ac
The cloud-config file uses the [YAML][yaml] file format, which uses whitespace and new-lines to delimit lists, associative arrays, and values.
A cloud-config file should contain an associative array which has zero or more of the following keys:
A cloud-config file must contain a header: either `#cloud-config` for processing as cloud-config (suggested) or `#!` for processing as a shell script (advanced). If cloud-config has #cloud-config header, it should followed by an associative array which has zero or more of the following keys:
- `coreos`
- `ssh_authorized_keys`
@@ -27,6 +37,8 @@ A cloud-config file should contain an associative array which has zero or more o
The expected values for these keys are defined in the rest of this document.
If cloud-config header starts on `#!` then coreos-cloudinit will recognize it as shell script which is interpreted by bash and run it as transient systemd service.
[yaml]: https://en.wikipedia.org/wiki/YAML
### Providing Cloud-Config with Config-Drive
@@ -37,27 +49,27 @@ CoreOS tries to conform to each platform's native method to provide user data. E
### coreos
#### etcd
#### etcd (deprecated. see etcd2)
The `coreos.etcd.*` parameters will be translated to a partial systemd unit acting as an etcd configuration file.
We can use the templating feature of coreos-cloudinit to automate etcd configuration with the `$private_ipv4` and `$public_ipv4` fields. For example, the following cloud-config document...
If the platform environment supports the templating feature of coreos-cloudinit it is possible to automate etcd configuration with the `$private_ipv4` and `$public_ipv4` fields. For example, the following cloud-config document...
```
```yaml
#cloud-config
coreos:
etcd:
name: node001
# generate a new token for each unique cluster from https://discovery.etcd.io/new
discovery: https://discovery.etcd.io/<token>
# multi-region and multi-cloud deployments need to use $public_ipv4
addr: $public_ipv4:4001
peer-addr: $private_ipv4:7001
etcd:
name: "node001"
# generate a new token for each unique cluster from https://discovery.etcd.io/new
discovery: "https://discovery.etcd.io/<token>"
# multi-region and multi-cloud deployments need to use $public_ipv4
addr: "$public_ipv4:4001"
peer-addr: "$private_ipv4:7001"
```
...will generate a systemd unit drop-in like this:
...will generate a systemd unit drop-in for etcd.service with the following contents:
```
```yaml
[Service]
Environment="ETCD_NAME=node001"
Environment="ETCD_DISCOVERY=https://discovery.etcd.io/<token>"
@@ -66,34 +78,157 @@ Environment="ETCD_PEER_ADDR=192.0.2.13:7001"
```
For more information about the available configuration parameters, see the [etcd documentation][etcd-config].
Note that hyphens in the coreos.etcd.* keys are mapped to underscores.
[etcd-config]: https://github.com/coreos/etcd/blob/master/Documentation/configuration.md
_Note: The `$private_ipv4` and `$public_ipv4` substitution variables referenced in other documents are only supported on Amazon EC2, Google Compute Engine, OpenStack, Rackspace, DigitalOcean, and Vagrant._
#### fleet
[etcd-config]: https://github.com/coreos/etcd/blob/release-0.4/Documentation/configuration.md
The `coreos.fleet.*` parameters work very similarly to `coreos.etcd.*`, and allow for the configuration of fleet through environment variables. For example, the following cloud-config document...
#### etcd2
```
The `coreos.etcd2.*` parameters will be translated to a partial systemd unit acting as an etcd configuration file.
If the platform environment supports the templating feature of coreos-cloudinit it is possible to automate etcd configuration with the `$private_ipv4` and `$public_ipv4` fields. When generating a [discovery token](https://discovery.etcd.io/new?size=3), set the `size` parameter, since etcd uses this to determine if all members have joined the cluster. After the cluster is bootstrapped, it can grow or shrink from this configured size.
For example, the following cloud-config document...
```yaml
#cloud-config
coreos:
fleet:
public-ip: $public_ipv4
metadata: region=us-west
etcd2:
# generate a new token for each unique cluster from https://discovery.etcd.io/new?size=3
discovery: "https://discovery.etcd.io/<token>"
# multi-region and multi-cloud deployments need to use $public_ipv4
advertise-client-urls: "http://$public_ipv4:2379"
initial-advertise-peer-urls: "http://$private_ipv4:2380"
# listen on both the official ports and the legacy ports
# legacy ports can be omitted if your application doesn't depend on them
listen-client-urls: "http://0.0.0.0:2379,http://0.0.0.0:4001"
listen-peer-urls: "http://$private_ipv4:2380,http://$private_ipv4:7001"
```
...will generate a systemd unit drop-in for etcd2.service with the following contents:
```yaml
[Service]
Environment="ETCD_DISCOVERY=https://discovery.etcd.io/<token>"
Environment="ETCD_ADVERTISE_CLIENT_URLS=http://203.0.113.29:2379"
Environment="ETCD_INITIAL_ADVERTISE_PEER_URLS=http://192.0.2.13:2380"
Environment="ETCD_LISTEN_CLIENT_URLS=http://0.0.0.0:2379,http://0.0.0.0:4001"
Environment="ETCD_LISTEN_PEER_URLS=http://192.0.2.13:2380,http://192.0.2.13:7001"
```
For more information about the available configuration parameters, see the [etcd2 documentation][etcd2-config].
_Note: The `$private_ipv4` and `$public_ipv4` substitution variables referenced in other documents are only supported on Amazon EC2, Google Compute Engine, OpenStack, Rackspace, DigitalOcean, and Vagrant._
[etcd2-config]: https://github.com/coreos/etcd/blob/master/Documentation/configuration.md
#### fleet
The `coreos.fleet.*` parameters work very similarly to `coreos.etcd2.*`, and allow for the configuration of fleet through environment variables. For example, the following cloud-config document...
```yaml
#cloud-config
coreos:
fleet:
public-ip: "$public_ipv4"
metadata: "region=us-west"
```
...will generate a systemd unit drop-in like this:
```
```yaml
[Service]
Environment="FLEET_PUBLIC_IP=203.0.113.29"
Environment="FLEET_METADATA=region=us-west"
```
List of fleet configuration parameters:
- **agent_ttl**: An Agent will be considered dead if it exceeds this amount of time to communicate with the Registry
- **engine_reconcile_interval**: Interval in seconds at which the engine should reconcile the cluster schedule in etcd
- **etcd_cafile**: Path to CA file used for TLS communication with etcd
- **etcd_certfile**: Provide TLS configuration when SSL certificate authentication is enabled in etcd endpoints
- **etcd_keyfile**: Path to private key file used for TLS communication with etcd
- **etcd_key_prefix**: etcd prefix path to be used for fleet keys
- **etcd_request_timeout**: Amount of time in seconds to allow a single etcd request before considering it failed
- **etcd_servers**: Comma separated list of etcd endpoints
- **metadata**: Comma separated key/value pairs that are published with the local to the fleet registry
- **public_ip**: IP accessible by other nodes for inter-host communication
- **verbosity**: Enable debug logging by setting this to an integer value greater than zero
For more information on fleet configuration, see the [fleet documentation][fleet-config].
[fleet-config]: https://github.com/coreos/fleet/blob/master/Documentation/configuration.md
[fleet-config]: https://github.com/coreos/fleet/blob/master/Documentation/deployment-and-configuration.md#configuration
#### flannel
The `coreos.flannel.*` parameters also work very similarly to `coreos.etcd2.*`
and `coreos.fleet.*`. They can be used to set environment variables for
flanneld. For example, the following cloud-config...
```yaml
#cloud-config
coreos:
flannel:
etcd_prefix: "/coreos.com/network2"
```
...will generate a systemd unit drop-in like so:
```
[Service]
Environment="FLANNELD_ETCD_PREFIX=/coreos.com/network2"
```
List of flannel configuration parameters:
- **etcd_endpoints**: Comma separated list of etcd endpoints
- **etcd_cafile**: Path to CA file used for TLS communication with etcd
- **etcd_certfile**: Path to certificate file used for TLS communication with etcd
- **etcd_keyfile**: Path to private key file used for TLS communication with etcd
- **etcd_prefix**: etcd prefix path to be used for flannel keys
- **ip_masq**: Install IP masquerade rules for traffic outside of flannel subnet
- **subnet_file**: Path to flannel subnet file to write out
- **interface**: Interface (name or IP) that should be used for inter-host communication
- **public_ip**: IP accessible by other nodes for inter-host communication
For more information on flannel configuration, see the [flannel documentation][flannel-readme].
[flannel-readme]: https://github.com/coreos/flannel/blob/master/README.md
#### locksmith
The `coreos.locksmith.*` parameters can be used to set environment variables
for locksmith. For example, the following cloud-config...
```yaml
#cloud-config
coreos:
locksmith:
endpoint: "http://example.com:2379"
```
...will generate a systemd unit drop-in like so:
```
[Service]
Environment="LOCKSMITHD_ENDPOINT=http://example.com:2379"
```
List of locksmith configuration parameters:
- **endpoint**: Comma separated list of etcd endpoints
- **etcd_cafile**: Path to CA file used for TLS communication with etcd
- **etcd_certfile**: Path to certificate file used for TLS communication with etcd
- **etcd_keyfile**: Path to private key file used for TLS communication with etcd
For the complete list of locksmith configuration parameters, see the [locksmith documentation][locksmith-readme].
[locksmith-readme]: https://github.com/coreos/locksmith/blob/master/README.md
#### update
@@ -107,30 +242,39 @@ The `reboot-strategy` parameter also affects the behaviour of [locksmith](https:
- _etcd-lock_: Reboot after first taking a distributed lock in etcd, this guarantees that only one host will reboot concurrently and that the cluster will remain available during the update.
- _best-effort_ - If etcd is running, "etcd-lock", otherwise simply "reboot".
- _off_ - Disable rebooting after updates are applied (not recommended).
- **server**: is the omaha endpoint URL which will be queried for updates.
- **server**: The location of the [CoreUpdate][coreupdate] server which will be queried for updates. Also known as the [omaha][omaha-docs] server endpoint.
- **group**: signifies the channel which should be used for automatic updates. This value defaults to the version of the image initially downloaded. (one of "master", "alpha", "beta", "stable")
[coreupdate]: https://coreos.com/products/coreupdate
[omaha-docs]: https://coreos.com/docs/coreupdate/custom-apps/coreupdate-protocol/
*Note: cloudinit will only manipulate the locksmith unit file in the systemd runtime directory (`/run/systemd/system/locksmithd.service`). If any manual modifications are made to an overriding unit configuration file (e.g. `/etc/systemd/system/locksmithd.service`), cloudinit will no longer be able to control the locksmith service unit.*
##### Example
```
```yaml
#cloud-config
coreos:
update:
reboot-strategy: etcd-lock
reboot-strategy: "etcd-lock"
```
#### units
The `coreos.units.*` parameters define a list of arbitrary systemd units to start. Each item is an object with the following fields:
The `coreos.units.*` parameters define a list of arbitrary systemd units to start after booting. This feature is intended to help you start essential services required to mount storage and configure networking in order to join the CoreOS cluster. It is not intended to be a Chef/Puppet replacement.
Each item is an object with the following fields:
- **name**: String representing unit's name. Required.
- **runtime**: Boolean indicating whether or not to persist the unit across reboots. This is analogous to the `--runtime` argument to `systemctl enable`. Default value is false.
- **enable**: Boolean indicating whether or not to handle the [Install] section of the unit file. This is similar to running `systemctl enable <name>`. Default value is false.
- **runtime**: Boolean indicating whether or not to persist the unit across reboots. This is analogous to the `--runtime` argument to `systemctl enable`. The default value is false.
- **enable**: Boolean indicating whether or not to handle the [Install] section of the unit file. This is similar to running `systemctl enable <name>`. The default value is false.
- **content**: Plaintext string representing entire unit file. If no value is provided, the unit is assumed to exist already.
- **command**: Command to execute on unit: start, stop, reload, restart, try-restart, reload-or-restart, reload-or-try-restart. Default value is restart.
- **mask**: Whether to mask the unit file by symlinking it to `/dev/null` (analogous to `systemctl mask <name>`). Note that unlike `systemctl mask`, **this will destructively remove any existing unit file** located at `/etc/systemd/system/<unit>`, to ensure that the mask succeeds. Default value is false.
- **command**: Command to execute on unit: start, stop, reload, restart, try-restart, reload-or-restart, reload-or-try-restart. The default behavior is to not execute any commands.
- **mask**: Whether to mask the unit file by symlinking it to `/dev/null` (analogous to `systemctl mask <name>`). Note that unlike `systemctl mask`, **this will destructively remove any existing unit file** located at `/etc/systemd/system/<unit>`, to ensure that the mask succeeds. The default value is false.
- **drop-ins**: A list of unit drop-ins with the following fields:
- **name**: String representing unit's name. Required.
- **content**: Plaintext string representing entire file. Required.
**NOTE:** The command field is ignored for all network, netdev, and link units. The systemd-networkd.service unit will be restarted in their place.
@@ -138,36 +282,51 @@ The `coreos.units.*` parameters define a list of arbitrary systemd units to star
Write a unit to disk, automatically starting it.
```
```yaml
#cloud-config
coreos:
units:
- name: docker-redis.service
command: start
content: |
[Unit]
Description=Redis container
Author=Me
After=docker.service
units:
- name: "docker-redis.service"
command: "start"
content: |
[Unit]
Description=Redis container
Author=Me
After=docker.service
[Service]
Restart=always
ExecStart=/usr/bin/docker start -a redis_server
ExecStop=/usr/bin/docker stop -t 2 redis_server
[Service]
Restart=always
ExecStart=/usr/bin/docker start -a redis_server
ExecStop=/usr/bin/docker stop -t 2 redis_server
```
Start the built-in `etcd` and `fleet` services:
Add the DOCKER_OPTS environment variable to docker.service.
```
```yaml
#cloud-config
coreos:
units:
- name: etcd.service
command: start
- name: fleet.service
command: start
units:
- name: "docker.service"
drop-ins:
- name: "50-insecure-registry.conf"
content: |
[Service]
Environment=DOCKER_OPTS='--insecure-registry="10.0.1.0/24"'
```
Start the built-in `etcd2` and `fleet` services:
```yaml
#cloud-config
coreos:
units:
- name: "etcd2.service"
command: "start"
- name: "fleet.service"
command: "start"
```
### ssh_authorized_keys
@@ -177,11 +336,11 @@ The `ssh_authorized_keys` parameter adds public SSH keys which will be authorize
The keys will be named "coreos-cloudinit" by default.
Override this by using the `--ssh-key-name` flag when calling `coreos-cloudinit`.
```
```yaml
#cloud-config
ssh_authorized_keys:
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC0g+ZTxC7weoIJLUafOgrm+h...
- "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC0g+ZTxC7weoIJLUafOgrm+h..."
```
### hostname
@@ -189,10 +348,10 @@ ssh_authorized_keys:
The `hostname` parameter defines the system's hostname.
This is the local part of a fully-qualified domain name (i.e. `foo` in `foo.example.com`).
```
```yaml
#cloud-config
hostname: coreos1
hostname: "coreos1"
```
### users
@@ -203,16 +362,18 @@ All but the `passwd` and `ssh-authorized-keys` fields will be ignored if the use
- **name**: Required. Login name of user
- **gecos**: GECOS comment of user
- **passwd**: Hash of the password to use for this user
- **homedir**: User's home directory. Defaults to /home/<name>
- **homedir**: User's home directory. Defaults to /home/\<name\>
- **no-create-home**: Boolean. Skip home directory creation.
- **primary-group**: Default group for the user. Defaults to a new group created named after the user.
- **groups**: Add user to these additional groups
- **no-user-group**: Boolean. Skip default group creation.
- **ssh-authorized-keys**: List of public SSH keys to authorize for this user
- **coreos-ssh-import-github**: Authorize SSH keys from Github user
- **coreos-ssh-import-url**: Authorize SSH keys imported from a url endpoint.
- **coreos-ssh-import-github** [DEPRECATED]: Authorize SSH keys from GitHub user
- **coreos-ssh-import-github-users** [DEPRECATED]: Authorize SSH keys from a list of GitHub users
- **coreos-ssh-import-url** [DEPRECATED]: Authorize SSH keys imported from a url endpoint.
- **system**: Create the user as a system user. No home directory will be created.
- **no-log-init**: Boolean. Skip initialization of lastlog and faillog databases.
- **shell**: User's login shell.
The following fields are not yet implemented:
@@ -222,17 +383,17 @@ The following fields are not yet implemented:
- **selinux-user**: Corresponding SELinux user
- **ssh-import-id**: Import SSH keys by ID from Launchpad.
```
```yaml
#cloud-config
users:
- name: elroy
passwd: $6$5s2u6/jR$un0AvWnqilcgaNB3Mkxd5yYv6mTlWfOoCYHZmfi3LDKVltj.E8XNKEcwWm...
- name: "elroy"
passwd: "$6$5s2u6/jR$un0AvWnqilcgaNB3Mkxd5yYv6mTlWfOoCYHZmfi3LDKVltj.E8XNKEcwWm..."
groups:
- sudo
- docker
- "sudo"
- "docker"
ssh-authorized-keys:
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC0g+ZTxC7weoIJLUafOgrm+h...
- "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC0g+ZTxC7weoIJLUafOgrm+h..."
```
#### Generating a password hash
@@ -255,63 +416,52 @@ perl -e 'print crypt("password","\$6\$SALT\$") . "\n"'
Using a higher number of rounds will help create more secure passwords, but given enough time, password hashes can be reversed. On most RPM based distributions there is a tool called mkpasswd available in the `expect` package, but this does not handle "rounds" nor advanced hashing algorithms.
#### Retrieving SSH Authorized Keys
##### From a GitHub User
Using the `coreos-ssh-import-github` field, we can import public SSH keys from a GitHub user to use as authorized keys to a server.
```
#cloud-config
users:
- name: elroy
coreos-ssh-import-github: elroy
```
##### From an HTTP Endpoint
We can also pull public SSH keys from any HTTP endpoint which matches [GitHub's API response format](https://developer.github.com/v3/users/keys/#list-public-keys-for-a-user).
For example, if you have an installation of GitHub Enterprise, you can provide a complete URL with an authentication token:
```
#cloud-config
users:
- name: elroy
coreos-ssh-import-url: https://github-enterprise.example.com/api/v3/users/elroy/keys?access_token=<TOKEN>
```
You can also specify any URL whose response matches the JSON format for public keys:
```
#cloud-config
users:
- name: elroy
coreos-ssh-import-url: https://example.com/public-keys
```
### write_files
The `write-file` parameter defines a list of files to create on the local filesystem. Each file is represented as an associative array which has the following keys:
The `write_files` directive defines a set of files to create on the local filesystem.
Each item in the list may have the following keys:
- **path**: Absolute location on disk where contents should be written
- **content**: Data to write at the provided `path`
- **permissions**: String representing file permissions in octal notation (i.e. '0644')
- **permissions**: Integer representing file permissions, typically in octal notation (i.e. 0644)
- **owner**: User and group that should own the file written to disk. This is equivalent to the `<user>:<group>` argument to `chown <user>:<group> <path>`.
- **encoding**: Optional. The encoding of the data in content. If not specified this defaults to the yaml document encoding (usually utf-8). Supported encoding types are:
- **b64, base64**: Base64 encoded content
- **gz, gzip**: gzip encoded content, for use with the !!binary tag
- **gz+b64, gz+base64, gzip+b64, gzip+base64**: Base64 encoded gzip content
Explicitly not implemented is the **encoding** attribute.
The **content** field must represent exactly what should be written to disk.
```
```yaml
#cloud-config
write_files:
- path: /etc/fleet/fleet.conf
permissions: 0644
- path: "/etc/resolv.conf"
permissions: "0644"
owner: "root"
content: |
verbosity=1
metadata="region=us-west,type=ssd"
nameserver 8.8.8.8
- path: "/etc/motd"
permissions: "0644"
owner: "root"
content: |
Good news, everyone!
- path: "/tmp/like_this"
permissions: "0644"
owner: "root"
encoding: "gzip"
content: !!binary |
H4sIAKgdh1QAAwtITM5WyK1USMqvUCjPLMlQSMssS1VIya9KzVPIySwszS9SyCpNLwYARQFQ5CcAAAA=
- path: "/tmp/or_like_this"
permissions: "0644"
owner: "root"
encoding: "gzip+base64"
content: |
H4sIAKgdh1QAAwtITM5WyK1USMqvUCjPLMlQSMssS1VIya9KzVPIySwszS9SyCpNLwYARQFQ5CcAAAA=
- path: "/tmp/todolist"
permissions: "0644"
owner: "root"
encoding: "base64"
content: |
UGFjayBteSBib3ggd2l0aCBmaXZlIGRvemVuIGxpcXVvciBqdWdz
```
### manage_etc_hosts
@@ -321,8 +471,8 @@ Currently, the only supported value is "localhost" which will cause your system'
to resolve to "127.0.0.1". This is helpful when the host does not have DNS
infrastructure in place to resolve its own hostname, for example, when using Vagrant.
```
```yaml
#cloud-config
manage_etc_hosts: localhost
manage_etc_hosts: "localhost"
```

View File

@@ -4,7 +4,7 @@ CoreOS supports providing configuration data via [config drive][config-drive]
disk images. Currently only providing a single script or cloud config file is
supported.
[config-drive]: http://docs.openstack.org/user-guide/content/enable_config_drive.html#config_drive_contents
[config-drive]: http://docs.openstack.org/user-guide/cli_config_drive.html
## Contents and Format
@@ -14,17 +14,27 @@ The image should be a single FAT or ISO9660 file system with the label
For example, to wrap up a config named `user_data` in a config drive image:
mkdir -p /tmp/new-drive/openstack/latest
cp user_data /tmp/new-drive/openstack/latest/user_data
mkisofs -R -V config-2 -o configdrive.iso /tmp/new-drive
rm -r /tmp/new-drive
```sh
mkdir -p /tmp/new-drive/openstack/latest
cp user_data /tmp/new-drive/openstack/latest/user_data
mkisofs -R -V config-2 -o configdrive.iso /tmp/new-drive
rm -r /tmp/new-drive
```
If on OS X, replace the `mkisofs` invocation with:
```sh
hdiutil makehybrid -iso -joliet -default-volume-name config-2 -o configdrive.iso /tmp/new-drive
```
## QEMU virtfs
One exception to the above, when using QEMU it is possible to skip creating an
image and use a plain directory containing the same contents:
qemu-system-x86_64 \
-fsdev local,id=conf,security_model=none,readonly,path=/tmp/new-drive \
-device virtio-9p-pci,fsdev=conf,mount_tag=config-2 \
[usual qemu options here...]
```sh
qemu-system-x86_64 \
-fsdev local,id=conf,security_model=none,readonly,path=/tmp/new-drive \
-device virtio-9p-pci,fsdev=conf,mount_tag=config-2 \
[usual qemu options here...]
```

View File

@@ -0,0 +1,27 @@
#Debian Interfaces#
**WARNING**: This option is EXPERIMENTAL and may change or be removed at any
point.
There is basic support for converting from a Debian network configuration to
networkd unit files. The -convert-netconf=debian option is used to activate
this feature.
#convert-netconf#
Default: ""
Read the network config provided in cloud-drive and translate it from the
specified format into networkd unit files (requires the -from-configdrive
flag). Currently only supports "debian" which provides support for a small
subset of the [Debian network configuration]
(https://wiki.debian.org/NetworkConfiguration). These options include:
- interface config methods
- static
- address/netmask
- gateway
- hwaddress
- dns-nameservers
- dhcp
- hwaddress
- manual
- loopback
- vlan_raw_device
- bond-slaves

View File

@@ -0,0 +1,35 @@
# VMWare Guestinfo Interface
## Cloud-Config VMWare Guestinfo Variables
coreos-cloudinit accepts configuration from the VMware RPC API's *guestinfo*
facility. This datasource can be enabled with the `--from-vmware-guestinfo`
flag to coreos-cloudinit.
The following guestinfo variables are recognized and processed by cloudinit
when passed from the hypervisor to the virtual machine at boot time. Note that
property names are prefixed with `guestinfo.` in the VMX, e.g., `guestinfo.hostname`.
| guestinfo variable | type |
|:--------------------------------------|:--------------------------------|
| `hostname` | `hostname` |
| `interface.<n>.name` | `string` |
| `interface.<n>.mac` | `MAC address` |
| `interface.<n>.dhcp` | `{"yes", "no"}` |
| `interface.<n>.role` | `{"public", "private"}` |
| `interface.<n>.ip.<m>.address` | `CIDR IP address` |
| `interface.<n>.route.<l>.gateway` | `IP address` |
| `interface.<n>.route.<l>.destination` | `CIDR IP address` |
| `dns.server.<x>` | `IP address` |
| `coreos.config.data` | `string` |
| `coreos.config.data.encoding` | `{"", "base64", "gzip+base64"}` |
| `coreos.config.url` | `URL` |
Note: "n", "m", "l", and "x" are 0-indexed, incrementing integers. The
identifier for an `interface` does not correspond to anything outside of this
configuration; it serves only to distinguish between multiple `interface`s.
The guide to [booting on VMWare][bootvmware] is the starting point for more
information about configuring and running CoreOS on VMWare.
[bootvmware]: https://github.com/coreos/docs/blob/master/os/booting-on-vmware.md

38
Godeps/Godeps.json generated Normal file
View File

@@ -0,0 +1,38 @@
{
"ImportPath": "github.com/coreos/coreos-cloudinit",
"GoVersion": "go1.3.3",
"Packages": [
"./..."
],
"Deps": [
{
"ImportPath": "github.com/cloudsigma/cepgo",
"Rev": "1bfc4895bf5c4d3b599f3f6ee142299488c8739b"
},
{
"ImportPath": "github.com/coreos/go-systemd/dbus",
"Rev": "4fbc5060a317b142e6c7bfbedb65596d5f0ab99b"
},
{
"ImportPath": "github.com/coreos/yaml",
"Rev": "6b16a5714269b2f70720a45406b1babd947a17ef"
},
{
"ImportPath": "github.com/dotcloud/docker/pkg/netlink",
"Comment": "v0.11.1-359-g55d41c3e21e1",
"Rev": "55d41c3e21e1593b944c06196ffb2ac57ab7f653"
},
{
"ImportPath": "github.com/guelfey/go.dbus",
"Rev": "f6a3a2366cc39b8479cadc499d3c735fb10fbdda"
},
{
"ImportPath": "github.com/tarm/goserial",
"Rev": "cdabc8d44e8e84f58f18074ae44337e1f2f375b9"
},
{
"ImportPath": "github.com/sigma/vmw-guestinfo",
"Rev": "de573afc542e0268fe8478d46e237fad9d6f7aec"
}
]
}

5
Godeps/Readme generated Normal file
View File

@@ -0,0 +1,5 @@
This directory tree is generated automatically by godep.
Please do not edit.
See https://github.com/tools/godep for more information.

2
Godeps/_workspace/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,2 @@
/pkg
/bin

View File

@@ -0,0 +1,23 @@
# Compiled Object files, Static and Dynamic libs (Shared Objects)
*.o
*.a
*.so
# Folders
_obj
_test
# Architecture specific extensions/prefixes
*.[568vq]
[568vq].out
*.cgo1.go
*.cgo2.c
_cgo_defun.c
_cgo_gotypes.go
_cgo_export.*
_testmain.go
*.exe
*.test

View File

@@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -0,0 +1,43 @@
cepgo
=====
Cepko implements easy-to-use communication with CloudSigma's VMs through a
virtual serial port without bothering with formatting the messages properly nor
parsing the output with the specific and sometimes confusing shell tools for
that purpose.
Having the server definition accessible by the VM can be useful in various
ways. For example it is possible to easily determine from within the VM, which
network interfaces are connected to public and which to private network.
Another use is to pass some data to initial VM setup scripts, like setting the
hostname to the VM name or passing ssh public keys through server meta.
Example usage:
package main
import (
"fmt"
"github.com/cloudsigma/cepgo"
)
func main() {
c := cepgo.NewCepgo()
result, err := c.Meta()
if err != nil {
panic(err)
}
fmt.Printf("%#v", result)
}
Output:
map[string]interface {}{
"optimize_for":"custom",
"ssh_public_key":"ssh-rsa AAA...",
"description":"[...]",
}
For more information take a look at the Server Context section of CloudSigma
API Docs: http://cloudsigma-docs.readthedocs.org/en/latest/server_context.html

View File

@@ -0,0 +1,186 @@
// Cepko implements easy-to-use communication with CloudSigma's VMs through a
// virtual serial port without bothering with formatting the messages properly
// nor parsing the output with the specific and sometimes confusing shell tools
// for that purpose.
//
// Having the server definition accessible by the VM can be useful in various
// ways. For example it is possible to easily determine from within the VM,
// which network interfaces are connected to public and which to private
// network. Another use is to pass some data to initial VM setup scripts, like
// setting the hostname to the VM name or passing ssh public keys through
// server meta.
//
// Example usage:
//
// package main
//
// import (
// "fmt"
//
// "github.com/cloudsigma/cepgo"
// )
//
// func main() {
// c := cepgo.NewCepgo()
// result, err := c.Meta()
// if err != nil {
// panic(err)
// }
// fmt.Printf("%#v", result)
// }
//
// Output:
//
// map[string]string{
// "optimize_for":"custom",
// "ssh_public_key":"ssh-rsa AAA...",
// "description":"[...]",
// }
//
// For more information take a look at the Server Context section API Docs:
// http://cloudsigma-docs.readthedocs.org/en/latest/server_context.html
package cepgo
import (
"bufio"
"encoding/json"
"errors"
"fmt"
"runtime"
"github.com/coreos/coreos-cloudinit/Godeps/_workspace/src/github.com/tarm/goserial"
)
const (
requestPattern = "<\n%s\n>"
EOT = '\x04' // End Of Transmission
)
var (
SerialPort string = "/dev/ttyS1"
Baud int = 115200
)
// Sets the serial port. If the operating system is windows CloudSigma's server
// context is at COM2 port, otherwise (linux, freebsd, darwin) the port is
// being left to the default /dev/ttyS1.
func init() {
if runtime.GOOS == "windows" {
SerialPort = "COM2"
}
}
// The default fetcher makes the connection to the serial port,
// writes given query and reads until the EOT symbol.
func fetchViaSerialPort(key string) ([]byte, error) {
config := &serial.Config{Name: SerialPort, Baud: Baud}
connection, err := serial.OpenPort(config)
if err != nil {
return nil, err
}
query := fmt.Sprintf(requestPattern, key)
if _, err := connection.Write([]byte(query)); err != nil {
return nil, err
}
reader := bufio.NewReader(connection)
answer, err := reader.ReadBytes(EOT)
if err != nil {
return nil, err
}
return answer[0 : len(answer)-1], nil
}
// Queries to the serial port can be executed only from instance of this type.
// The result from each of them can be either interface{}, map[string]string or
// a single in case of single value is returned. There is also a public metod
// who directly calls the fetcher and returns raw []byte from the serial port.
type Cepgo struct {
fetcher func(string) ([]byte, error)
}
// Creates a Cepgo instance with the default serial port fetcher.
func NewCepgo() *Cepgo {
cepgo := new(Cepgo)
cepgo.fetcher = fetchViaSerialPort
return cepgo
}
// Creates a Cepgo instance with custom fetcher.
func NewCepgoFetcher(fetcher func(string) ([]byte, error)) *Cepgo {
cepgo := new(Cepgo)
cepgo.fetcher = fetcher
return cepgo
}
// Fetches raw []byte from the serial port using directly the fetcher member.
func (c *Cepgo) FetchRaw(key string) ([]byte, error) {
return c.fetcher(key)
}
// Fetches a single key and tries to unmarshal the result to json and returns
// it. If the unmarshalling fails it's safe to assume the result it's just a
// string and returns it.
func (c *Cepgo) Key(key string) (interface{}, error) {
var result interface{}
fetched, err := c.FetchRaw(key)
if err != nil {
return nil, err
}
err = json.Unmarshal(fetched, &result)
if err != nil {
return string(fetched), nil
}
return result, nil
}
// Fetches all the server context. Equivalent of c.Key("")
func (c *Cepgo) All() (interface{}, error) {
return c.Key("")
}
// Fetches only the object meta field and makes sure to return a proper
// map[string]string
func (c *Cepgo) Meta() (map[string]string, error) {
rawMeta, err := c.Key("/meta/")
if err != nil {
return nil, err
}
return typeAssertToMapOfStrings(rawMeta)
}
// Fetches only the global context and makes sure to return a proper
// map[string]string
func (c *Cepgo) GlobalContext() (map[string]string, error) {
rawContext, err := c.Key("/global_context/")
if err != nil {
return nil, err
}
return typeAssertToMapOfStrings(rawContext)
}
// Just a little helper function that uses type assertions in order to convert
// a interface{} to map[string]string if this is possible.
func typeAssertToMapOfStrings(raw interface{}) (map[string]string, error) {
result := make(map[string]string)
dictionary, ok := raw.(map[string]interface{})
if !ok {
return nil, errors.New("Received bytes are formatted badly")
}
for key, rawValue := range dictionary {
if value, ok := rawValue.(string); ok {
result[key] = value
} else {
return nil, errors.New("Server context metadata is formatted badly")
}
}
return result, nil
}

View File

@@ -0,0 +1,122 @@
package cepgo
import (
"encoding/json"
"testing"
)
func fetchMock(key string) ([]byte, error) {
context := []byte(`{
"context": true,
"cpu": 4000,
"cpu_model": null,
"cpus_instead_of_cores": false,
"enable_numa": false,
"global_context": {
"some_global_key": "some_global_val"
},
"grantees": [],
"hv_relaxed": false,
"hv_tsc": false,
"jobs": [],
"mem": 4294967296,
"meta": {
"base64_fields": "cloudinit-user-data",
"cloudinit-user-data": "I2Nsb3VkLWNvbmZpZwoKaG9zdG5hbWU6IGNvcmVvczE=",
"ssh_public_key": "ssh-rsa AAAAB2NzaC1yc2E.../hQ5D5 john@doe"
},
"name": "coreos",
"nics": [
{
"runtime": {
"interface_type": "public",
"ip_v4": {
"uuid": "31.171.251.74"
},
"ip_v6": null
},
"vlan": null
}
],
"smp": 2,
"status": "running",
"uuid": "20a0059b-041e-4d0c-bcc6-9b2852de48b3"
}`)
if key == "" {
return context, nil
}
var marshalledContext map[string]interface{}
err := json.Unmarshal(context, &marshalledContext)
if err != nil {
return nil, err
}
if key[0] == '/' {
key = key[1:]
}
if key[len(key)-1] == '/' {
key = key[:len(key)-1]
}
return json.Marshal(marshalledContext[key])
}
func TestAll(t *testing.T) {
cepgo := NewCepgoFetcher(fetchMock)
result, err := cepgo.All()
if err != nil {
t.Error(err)
}
for _, key := range []string{"meta", "name", "uuid", "global_context"} {
if _, ok := result.(map[string]interface{})[key]; !ok {
t.Errorf("%s not in all keys", key)
}
}
}
func TestKey(t *testing.T) {
cepgo := NewCepgoFetcher(fetchMock)
result, err := cepgo.Key("uuid")
if err != nil {
t.Error(err)
}
if _, ok := result.(string); !ok {
t.Errorf("%#v\n", result)
t.Error("Fetching the uuid did not return a string")
}
}
func TestMeta(t *testing.T) {
cepgo := NewCepgoFetcher(fetchMock)
meta, err := cepgo.Meta()
if err != nil {
t.Errorf("%#v\n", meta)
t.Error(err)
}
if _, ok := meta["ssh_public_key"]; !ok {
t.Error("ssh_public_key is not in the meta")
}
}
func TestGlobalContext(t *testing.T) {
cepgo := NewCepgoFetcher(fetchMock)
result, err := cepgo.GlobalContext()
if err != nil {
t.Error(err)
}
if _, ok := result["some_global_key"]; !ok {
t.Error("some_global_key is not in the global context")
}
}

View File

@@ -23,7 +23,7 @@ import (
"strings"
"sync"
"github.com/coreos/coreos-cloudinit/third_party/github.com/guelfey/go.dbus"
"github.com/coreos/coreos-cloudinit/Godeps/_workspace/src/github.com/guelfey/go.dbus"
)
const signalBuffer = 100

View File

@@ -18,7 +18,7 @@ package dbus
import (
"errors"
"github.com/coreos/coreos-cloudinit/third_party/github.com/guelfey/go.dbus"
"github.com/coreos/coreos-cloudinit/Godeps/_workspace/src/github.com/guelfey/go.dbus"
)
func (c *Conn) initJobs() {
@@ -208,7 +208,7 @@ func (c *Conn) SetUnitProperties(name string, runtime bool, properties ...Proper
}
func (c *Conn) GetUnitTypeProperty(unit string, unitType string, propertyName string) (*Property, error) {
return c.getProperty(unit, "org.freedesktop.systemd1." + unitType, propertyName)
return c.getProperty(unit, "org.freedesktop.systemd1."+unitType, propertyName)
}
// ListUnits returns an array with all currently loaded units. Note that

View File

@@ -18,7 +18,7 @@ package dbus
import (
"fmt"
"github.com/coreos/coreos-cloudinit/third_party/github.com/guelfey/go.dbus"
"github.com/coreos/coreos-cloudinit/Godeps/_workspace/src/github.com/guelfey/go.dbus"
"math/rand"
"os"
"path/filepath"

View File

@@ -17,7 +17,7 @@ limitations under the License.
package dbus
import (
"github.com/coreos/coreos-cloudinit/third_party/github.com/guelfey/go.dbus"
"github.com/coreos/coreos-cloudinit/Godeps/_workspace/src/github.com/guelfey/go.dbus"
)
// From the systemd docs:

View File

@@ -20,7 +20,7 @@ import (
"errors"
"time"
"github.com/coreos/coreos-cloudinit/third_party/github.com/guelfey/go.dbus"
"github.com/coreos/coreos-cloudinit/Godeps/_workspace/src/github.com/guelfey/go.dbus"
)
const (
@@ -101,7 +101,7 @@ func (c *Conn) SubscribeUnits(interval time.Duration) (<-chan map[string]*UnitSt
// SubscribeUnitsCustom is like SubscribeUnits but lets you specify the buffer
// size of the channels, the comparison function for detecting changes and a filter
// function for cutting down on the noise that your channel receives.
func (c *Conn) SubscribeUnitsCustom(interval time.Duration, buffer int, isChanged func(*UnitStatus, *UnitStatus) bool, filterUnit func (string) bool) (<-chan map[string]*UnitStatus, <-chan error) {
func (c *Conn) SubscribeUnitsCustom(interval time.Duration, buffer int, isChanged func(*UnitStatus, *UnitStatus) bool, filterUnit func(string) bool) (<-chan map[string]*UnitStatus, <-chan error) {
old := make(map[string]*UnitStatus)
statusChan := make(chan map[string]*UnitStatus, buffer)
errChan := make(chan error, buffer)

View File

@@ -1,3 +1,6 @@
Copyright (c) 2011-2014 - Canonical Inc.
This software is licensed under the LGPLv3, included below.
As a special exception to the GNU Lesser General Public License version 3

View File

@@ -1,3 +1,15 @@
The following files were ported to Go from C files of libyaml, and thus
are still covered by their original copyright and license:
apic.go
emitterc.go
parserc.go
readerc.go
scannerc.go
writerc.go
yamlh.go
yamlprivateh.go
Copyright (c) 2006 Kirill Simonov
Permission is hereby granted, free of charge, to any person obtaining a copy of

131
Godeps/_workspace/src/github.com/coreos/yaml/README.md generated vendored Normal file
View File

@@ -0,0 +1,131 @@
Note: This is a fork of https://github.com/go-yaml/yaml. The following README
doesn't necessarily apply to this fork.
# YAML support for the Go language
Introduction
------------
The yaml package enables Go programs to comfortably encode and decode YAML
values. It was developed within [Canonical](https://www.canonical.com) as
part of the [juju](https://juju.ubuntu.com) project, and is based on a
pure Go port of the well-known [libyaml](http://pyyaml.org/wiki/LibYAML)
C library to parse and generate YAML data quickly and reliably.
Compatibility
-------------
The yaml package supports most of YAML 1.1 and 1.2, including support for
anchors, tags, map merging, etc. Multi-document unmarshalling is not yet
implemented, and base-60 floats from YAML 1.1 are purposefully not
supported since they're a poor design and are gone in YAML 1.2.
Installation and usage
----------------------
The import path for the package is *gopkg.in/yaml.v1*.
To install it, run:
go get gopkg.in/yaml.v1
API documentation
-----------------
If opened in a browser, the import path itself leads to the API documentation:
* [https://gopkg.in/yaml.v1](https://gopkg.in/yaml.v1)
API stability
-------------
The package API for yaml v1 will remain stable as described in [gopkg.in](https://gopkg.in).
License
-------
The yaml package is licensed under the LGPL with an exception that allows it to be linked statically. Please see the LICENSE file for details.
Example
-------
```Go
package main
import (
"fmt"
"log"
"gopkg.in/yaml.v1"
)
var data = `
a: Easy!
b:
c: 2
d: [3, 4]
`
type T struct {
A string
B struct{C int; D []int ",flow"}
}
func main() {
t := T{}
err := yaml.Unmarshal([]byte(data), &t)
if err != nil {
log.Fatalf("error: %v", err)
}
fmt.Printf("--- t:\n%v\n\n", t)
d, err := yaml.Marshal(&t)
if err != nil {
log.Fatalf("error: %v", err)
}
fmt.Printf("--- t dump:\n%s\n\n", string(d))
m := make(map[interface{}]interface{})
err = yaml.Unmarshal([]byte(data), &m)
if err != nil {
log.Fatalf("error: %v", err)
}
fmt.Printf("--- m:\n%v\n\n", m)
d, err = yaml.Marshal(&m)
if err != nil {
log.Fatalf("error: %v", err)
}
fmt.Printf("--- m dump:\n%s\n\n", string(d))
}
```
This example will generate the following output:
```
--- t:
{Easy! {2 [3 4]}}
--- t dump:
a: Easy!
b:
c: 2
d: [3, 4]
--- m:
map[a:Easy! b:map[c:2 d:[3 4]]]
--- m dump:
a: Easy!
b:
c: 2
d:
- 3
- 4
```

View File

@@ -1,4 +1,4 @@
package goyaml
package yaml
import (
"io"

View File

@@ -1,8 +1,11 @@
package goyaml
package yaml
import (
"encoding/base64"
"fmt"
"reflect"
"strconv"
"time"
)
const (
@@ -27,13 +30,15 @@ type node struct {
// Parser, produces a node tree out of a libyaml event stream.
type parser struct {
parser yaml_parser_t
event yaml_event_t
doc *node
parser yaml_parser_t
event yaml_event_t
doc *node
transform transformString
}
func newParser(b []byte) *parser {
p := parser{}
func newParser(b []byte, t transformString) *parser {
p := parser{transform: t}
if !yaml_parser_initialize(&p.parser) {
panic("Failed to initialize YAML emitter")
}
@@ -62,7 +67,7 @@ func (p *parser) destroy() {
func (p *parser) skip() {
if p.event.typ != yaml_NO_EVENT {
if p.event.typ == yaml_STREAM_END_EVENT {
panic("Attempted to go past the end of stream. Corrupted value?")
fail("Attempted to go past the end of stream. Corrupted value?")
}
yaml_event_delete(&p.event)
}
@@ -88,7 +93,7 @@ func (p *parser) fail() {
} else {
msg = "Unknown problem parsing YAML content"
}
panic(where + msg)
fail(where + msg)
}
func (p *parser) anchor(n *node, anchor []byte) {
@@ -113,10 +118,9 @@ func (p *parser) parse() *node {
// Happens when attempting to decode an empty buffer.
return nil
default:
panic("Attempted to parse unknown event: " +
strconv.Itoa(int(p.event.typ)))
panic("Attempted to parse unknown event: " + strconv.Itoa(int(p.event.typ)))
}
panic("Unreachable")
panic("unreachable")
}
func (p *parser) node(kind int) *node {
@@ -134,8 +138,7 @@ func (p *parser) document() *node {
p.skip()
n.children = append(n.children, p.parse())
if p.event.typ != yaml_DOCUMENT_END_EVENT {
panic("Expected end of document event but got " +
strconv.Itoa(int(p.event.typ)))
panic("Expected end of document event but got " + strconv.Itoa(int(p.event.typ)))
}
p.skip()
return n
@@ -174,7 +177,10 @@ func (p *parser) mapping() *node {
p.anchor(n, p.event.anchor)
p.skip()
for p.event.typ != yaml_MAPPING_END_EVENT {
n.children = append(n.children, p.parse(), p.parse())
key := p.parse()
key.value = p.transform(key.value)
value := p.parse()
n.children = append(n.children, key, value)
}
p.skip()
return n
@@ -211,11 +217,21 @@ func newDecoder() *decoder {
// returned to call SetYAML() with the value of *out once it's defined.
//
func (d *decoder) setter(tag string, out *reflect.Value, good *bool) (set func()) {
if (*out).Kind() != reflect.Ptr && (*out).CanAddr() {
setter, _ := (*out).Addr().Interface().(Setter)
if setter != nil {
var arg interface{}
*out = reflect.ValueOf(&arg).Elem()
return func() {
*good = setter.SetYAML(shortTag(tag), arg)
}
}
}
again := true
for again {
again = false
setter, _ := (*out).Interface().(Setter)
if tag != "!!null" || setter != nil {
if tag != yaml_NULL_TAG || setter != nil {
if pv := (*out); pv.Kind() == reflect.Ptr {
if pv.IsNil() {
*out = reflect.New(pv.Type().Elem()).Elem()
@@ -231,7 +247,7 @@ func (d *decoder) setter(tag string, out *reflect.Value, good *bool) (set func()
var arg interface{}
*out = reflect.ValueOf(&arg).Elem()
return func() {
*good = setter.SetYAML(tag, arg)
*good = setter.SetYAML(shortTag(tag), arg)
}
}
}
@@ -268,10 +284,10 @@ func (d *decoder) document(n *node, out reflect.Value) (good bool) {
func (d *decoder) alias(n *node, out reflect.Value) (good bool) {
an, ok := d.doc.anchors[n.value]
if !ok {
panic("Unknown anchor '" + n.value + "' referenced")
fail("Unknown anchor '" + n.value + "' referenced")
}
if d.aliases[n.value] {
panic("Anchor '" + n.value + "' value contains itself")
fail("Anchor '" + n.value + "' value contains itself")
}
d.aliases[n.value] = true
good = d.unmarshal(an, out)
@@ -279,20 +295,50 @@ func (d *decoder) alias(n *node, out reflect.Value) (good bool) {
return good
}
var zeroValue reflect.Value
func resetMap(out reflect.Value) {
for _, k := range out.MapKeys() {
out.SetMapIndex(k, zeroValue)
}
}
var durationType = reflect.TypeOf(time.Duration(0))
func (d *decoder) scalar(n *node, out reflect.Value) (good bool) {
var tag string
var resolved interface{}
if n.tag == "" && !n.implicit {
tag = yaml_STR_TAG
resolved = n.value
} else {
tag, resolved = resolve(n.tag, n.value)
if set := d.setter(tag, &out, &good); set != nil {
defer set()
if tag == yaml_BINARY_TAG {
data, err := base64.StdEncoding.DecodeString(resolved.(string))
if err != nil {
fail("!!binary value contains invalid base64 data")
}
resolved = string(data)
}
}
if set := d.setter(tag, &out, &good); set != nil {
defer set()
}
if resolved == nil {
if out.Kind() == reflect.Map && !out.CanAddr() {
resetMap(out)
} else {
out.Set(reflect.Zero(out.Type()))
}
good = true
return
}
switch out.Kind() {
case reflect.String:
if resolved != nil {
if tag == yaml_BINARY_TAG {
out.SetString(resolved.(string))
good = true
} else if resolved != nil {
out.SetString(n.value)
good = true
}
@@ -320,6 +366,14 @@ func (d *decoder) scalar(n *node, out reflect.Value) (good bool) {
out.SetInt(int64(resolved))
good = true
}
case string:
if out.Type() == durationType {
d, err := time.ParseDuration(resolved)
if err == nil {
out.SetInt(int64(d))
good = true
}
}
}
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
switch resolved := resolved.(type) {
@@ -358,17 +412,11 @@ func (d *decoder) scalar(n *node, out reflect.Value) (good bool) {
good = true
}
case reflect.Ptr:
switch resolved.(type) {
case nil:
out.Set(reflect.Zero(out.Type()))
if out.Type().Elem() == reflect.TypeOf(resolved) {
elem := reflect.New(out.Type().Elem())
elem.Elem().Set(reflect.ValueOf(resolved))
out.Set(elem)
good = true
default:
if out.Type().Elem() == reflect.TypeOf(resolved) {
elem := reflect.New(out.Type().Elem())
elem.Elem().Set(reflect.ValueOf(resolved))
out.Set(elem)
good = true
}
}
}
return good
@@ -382,7 +430,7 @@ func settableValueOf(i interface{}) reflect.Value {
}
func (d *decoder) sequence(n *node, out reflect.Value) (good bool) {
if set := d.setter("!!seq", &out, &good); set != nil {
if set := d.setter(yaml_SEQ_TAG, &out, &good); set != nil {
defer set()
}
var iface reflect.Value
@@ -411,7 +459,7 @@ func (d *decoder) sequence(n *node, out reflect.Value) (good bool) {
}
func (d *decoder) mapping(n *node, out reflect.Value) (good bool) {
if set := d.setter("!!map", &out, &good); set != nil {
if set := d.setter(yaml_MAP_TAG, &out, &good); set != nil {
defer set()
}
if out.Kind() == reflect.Struct {
@@ -437,8 +485,19 @@ func (d *decoder) mapping(n *node, out reflect.Value) (good bool) {
}
l := len(n.children)
for i := 0; i < l; i += 2 {
if isMerge(n.children[i]) {
d.merge(n.children[i+1], out)
continue
}
k := reflect.New(kt).Elem()
if d.unmarshal(n.children[i], k) {
kkind := k.Kind()
if kkind == reflect.Interface {
kkind = k.Elem().Kind()
}
if kkind == reflect.Map || kkind == reflect.Slice {
fail(fmt.Sprintf("invalid map key: %#v", k.Interface()))
}
e := reflect.New(et).Elem()
if d.unmarshal(n.children[i+1], e) {
out.SetMapIndex(k, e)
@@ -456,7 +515,12 @@ func (d *decoder) mappingStruct(n *node, out reflect.Value) (good bool) {
name := settableValueOf("")
l := len(n.children)
for i := 0; i < l; i += 2 {
if !d.unmarshal(n.children[i], name) {
ni := n.children[i]
if isMerge(ni) {
d.merge(n.children[i+1], out)
continue
}
if !d.unmarshal(ni, name) {
continue
}
if info, ok := sinfo.FieldsMap[name.String()]; ok {
@@ -471,3 +535,37 @@ func (d *decoder) mappingStruct(n *node, out reflect.Value) (good bool) {
}
return true
}
func (d *decoder) merge(n *node, out reflect.Value) {
const wantMap = "map merge requires map or sequence of maps as the value"
switch n.kind {
case mappingNode:
d.unmarshal(n, out)
case aliasNode:
an, ok := d.doc.anchors[n.value]
if ok && an.kind != mappingNode {
fail(wantMap)
}
d.unmarshal(n, out)
case sequenceNode:
// Step backwards as earlier nodes take precedence.
for i := len(n.children) - 1; i >= 0; i-- {
ni := n.children[i]
if ni.kind == aliasNode {
an, ok := d.doc.anchors[ni.value]
if ok && an.kind != mappingNode {
fail(wantMap)
}
} else if ni.kind != mappingNode {
fail(wantMap)
}
d.unmarshal(ni, out)
}
default:
fail(wantMap)
}
}
func isMerge(n *node) bool {
return n.kind == scalarNode && n.value == "<<" && (n.implicit == true || n.tag == yaml_MERGE_TAG)
}

View File

@@ -1,10 +1,12 @@
package goyaml_test
package yaml_test
import (
. "launchpad.net/gocheck"
"github.com/coreos/coreos-cloudinit/third_party/launchpad.net/goyaml"
"github.com/coreos/yaml"
. "gopkg.in/check.v1"
"math"
"reflect"
"strings"
"time"
)
var unmarshalIntTest = 123
@@ -315,7 +317,10 @@ var unmarshalTests = []struct {
map[string]*string{"foo": new(string)},
}, {
"foo: null",
map[string]string{},
map[string]string{"foo": ""},
}, {
"foo: null",
map[string]interface{}{"foo": nil},
},
// Ignored field
@@ -350,6 +355,50 @@ var unmarshalTests = []struct {
C inlineB `yaml:",inline"`
}{1, inlineB{2, inlineC{3}}},
},
// bug 1243827
{
"a: -b_c",
map[string]interface{}{"a": "-b_c"},
},
{
"a: +b_c",
map[string]interface{}{"a": "+b_c"},
},
{
"a: 50cent_of_dollar",
map[string]interface{}{"a": "50cent_of_dollar"},
},
// Duration
{
"a: 3s",
map[string]time.Duration{"a": 3 * time.Second},
},
// Issue #24.
{
"a: <foo>",
map[string]string{"a": "<foo>"},
},
// Base 60 floats are obsolete and unsupported.
{
"a: 1:1\n",
map[string]string{"a": "1:1"},
},
// Binary data.
{
"a: !!binary gIGC\n",
map[string]string{"a": "\x80\x81\x82"},
}, {
"a: !!binary |\n " + strings.Repeat("kJCQ", 17) + "kJ\n CQ\n",
map[string]string{"a": strings.Repeat("\x90", 54)},
}, {
"a: !!binary |\n " + strings.Repeat("A", 70) + "\n ==\n",
map[string]string{"a": strings.Repeat("\x00", 52)},
},
}
type inlineB struct {
@@ -377,7 +426,7 @@ func (s *S) TestUnmarshal(c *C) {
pv := reflect.New(pt.Elem())
value = pv.Interface()
}
err := goyaml.Unmarshal([]byte(item.data), value)
err := yaml.Unmarshal([]byte(item.data), value)
c.Assert(err, IsNil, Commentf("Item #%d", i))
if t.Kind() == reflect.String {
c.Assert(*value.(*string), Equals, item.value, Commentf("Item #%d", i))
@@ -389,7 +438,7 @@ func (s *S) TestUnmarshal(c *C) {
func (s *S) TestUnmarshalNaN(c *C) {
value := map[string]interface{}{}
err := goyaml.Unmarshal([]byte("notanum: .NaN"), &value)
err := yaml.Unmarshal([]byte("notanum: .NaN"), &value)
c.Assert(err, IsNil)
c.Assert(math.IsNaN(value["notanum"].(float64)), Equals, true)
}
@@ -397,18 +446,21 @@ func (s *S) TestUnmarshalNaN(c *C) {
var unmarshalErrorTests = []struct {
data, error string
}{
{"v: !!float 'error'", "YAML error: Can't decode !!str 'error' as a !!float"},
{"v: !!float 'error'", "YAML error: cannot decode !!str `error` as a !!float"},
{"v: [A,", "YAML error: line 1: did not find expected node content"},
{"v:\n- [A,", "YAML error: line 2: did not find expected node content"},
{"a: *b\n", "YAML error: Unknown anchor 'b' referenced"},
{"a: &a\n b: *a\n", "YAML error: Anchor 'a' value contains itself"},
{"value: -", "YAML error: block sequence entries are not allowed in this context"},
{"a: !!binary ==", "YAML error: !!binary value contains invalid base64 data"},
{"{[.]}", `YAML error: invalid map key: \[\]interface \{\}\{"\."\}`},
{"{{.}}", `YAML error: invalid map key: map\[interface\ \{\}\]interface \{\}\{".":interface \{\}\(nil\)\}`},
}
func (s *S) TestUnmarshalErrors(c *C) {
for _, item := range unmarshalErrorTests {
var value interface{}
err := goyaml.Unmarshal([]byte(item.data), &value)
err := yaml.Unmarshal([]byte(item.data), &value)
c.Assert(err, ErrorMatches, item.error, Commentf("Partial unmarshal: %#v", value))
}
}
@@ -421,6 +473,8 @@ var setterTests = []struct {
{"_: [1,A]", "!!seq", []interface{}{1, "A"}},
{"_: 10", "!!int", 10},
{"_: null", "!!null", nil},
{`_: BAR!`, "!!str", "BAR!"},
{`_: "BAR!"`, "!!str", "BAR!"},
{"_: !!foo 'BAR!'", "!!foo", "BAR!"},
}
@@ -442,17 +496,31 @@ func (o *typeWithSetter) SetYAML(tag string, value interface{}) (ok bool) {
return true
}
type typeWithSetterField struct {
type setterPointerType struct {
Field *typeWithSetter "_"
}
func (s *S) TestUnmarshalWithSetter(c *C) {
type setterValueType struct {
Field typeWithSetter "_"
}
func (s *S) TestUnmarshalWithPointerSetter(c *C) {
for _, item := range setterTests {
obj := &typeWithSetterField{}
err := goyaml.Unmarshal([]byte(item.data), obj)
obj := &setterPointerType{}
err := yaml.Unmarshal([]byte(item.data), obj)
c.Assert(err, IsNil)
c.Assert(obj.Field, NotNil,
Commentf("Pointer not initialized (%#v)", item.value))
c.Assert(obj.Field, NotNil, Commentf("Pointer not initialized (%#v)", item.value))
c.Assert(obj.Field.tag, Equals, item.tag)
c.Assert(obj.Field.value, DeepEquals, item.value)
}
}
func (s *S) TestUnmarshalWithValueSetter(c *C) {
for _, item := range setterTests {
obj := &setterValueType{}
err := yaml.Unmarshal([]byte(item.data), obj)
c.Assert(err, IsNil)
c.Assert(obj.Field, NotNil, Commentf("Pointer not initialized (%#v)", item.value))
c.Assert(obj.Field.tag, Equals, item.tag)
c.Assert(obj.Field.value, DeepEquals, item.value)
}
@@ -460,7 +528,7 @@ func (s *S) TestUnmarshalWithSetter(c *C) {
func (s *S) TestUnmarshalWholeDocumentWithSetter(c *C) {
obj := &typeWithSetter{}
err := goyaml.Unmarshal([]byte(setterTests[0].data), obj)
err := yaml.Unmarshal([]byte(setterTests[0].data), obj)
c.Assert(err, IsNil)
c.Assert(obj.tag, Equals, setterTests[0].tag)
value, ok := obj.value.(map[interface{}]interface{})
@@ -477,8 +545,8 @@ func (s *S) TestUnmarshalWithFalseSetterIgnoresValue(c *C) {
}()
m := map[string]*typeWithSetter{}
data := "{abc: 1, def: 2, ghi: 3, jkl: 4}"
err := goyaml.Unmarshal([]byte(data), m)
data := `{abc: 1, def: 2, ghi: 3, jkl: 4}`
err := yaml.Unmarshal([]byte(data), m)
c.Assert(err, IsNil)
c.Assert(m["abc"], NotNil)
c.Assert(m["def"], IsNil)
@@ -489,6 +557,139 @@ func (s *S) TestUnmarshalWithFalseSetterIgnoresValue(c *C) {
c.Assert(m["ghi"].value, Equals, 3)
}
func (s *S) TestUnmarshalWithTransform(c *C) {
data := `{a_b: 1, c-d: 2, e-f_g: 3, h_i-j: 4}`
expect := map[string]int{
"a_b": 1,
"c_d": 2,
"e_f_g": 3,
"h_i_j": 4,
}
m := map[string]int{}
yaml.UnmarshalMappingKeyTransform = func(i string) string {
return strings.Replace(i, "-", "_", -1)
}
err := yaml.Unmarshal([]byte(data), m)
c.Assert(err, IsNil)
c.Assert(m, DeepEquals, expect)
}
// From http://yaml.org/type/merge.html
var mergeTests = `
anchors:
- &CENTER { "x": 1, "y": 2 }
- &LEFT { "x": 0, "y": 2 }
- &BIG { "r": 10 }
- &SMALL { "r": 1 }
# All the following maps are equal:
plain:
# Explicit keys
"x": 1
"y": 2
"r": 10
label: center/big
mergeOne:
# Merge one map
<< : *CENTER
"r": 10
label: center/big
mergeMultiple:
# Merge multiple maps
<< : [ *CENTER, *BIG ]
label: center/big
override:
# Override
<< : [ *BIG, *LEFT, *SMALL ]
"x": 1
label: center/big
shortTag:
# Explicit short merge tag
!!merge "<<" : [ *CENTER, *BIG ]
label: center/big
longTag:
# Explicit merge long tag
!<tag:yaml.org,2002:merge> "<<" : [ *CENTER, *BIG ]
label: center/big
inlineMap:
# Inlined map
<< : {"x": 1, "y": 2, "r": 10}
label: center/big
inlineSequenceMap:
# Inlined map in sequence
<< : [ *CENTER, {"r": 10} ]
label: center/big
`
func (s *S) TestMerge(c *C) {
var want = map[interface{}]interface{}{
"x": 1,
"y": 2,
"r": 10,
"label": "center/big",
}
var m map[string]interface{}
err := yaml.Unmarshal([]byte(mergeTests), &m)
c.Assert(err, IsNil)
for name, test := range m {
if name == "anchors" {
continue
}
c.Assert(test, DeepEquals, want, Commentf("test %q failed", name))
}
}
func (s *S) TestMergeStruct(c *C) {
type Data struct {
X, Y, R int
Label string
}
want := Data{1, 2, 10, "center/big"}
var m map[string]Data
err := yaml.Unmarshal([]byte(mergeTests), &m)
c.Assert(err, IsNil)
for name, test := range m {
if name == "anchors" {
continue
}
c.Assert(test, Equals, want, Commentf("test %q failed", name))
}
}
var unmarshalNullTests = []func() interface{}{
func() interface{} { var v interface{}; v = "v"; return &v },
func() interface{} { var s = "s"; return &s },
func() interface{} { var s = "s"; sptr := &s; return &sptr },
func() interface{} { var i = 1; return &i },
func() interface{} { var i = 1; iptr := &i; return &iptr },
func() interface{} { m := map[string]int{"s": 1}; return &m },
func() interface{} { m := map[string]int{"s": 1}; return m },
}
func (s *S) TestUnmarshalNull(c *C) {
for _, test := range unmarshalNullTests {
item := test()
zero := reflect.Zero(reflect.TypeOf(item).Elem()).Interface()
err := yaml.Unmarshal([]byte("null"), item)
c.Assert(err, IsNil)
if reflect.TypeOf(item).Kind() == reflect.Map {
c.Assert(reflect.ValueOf(item).Interface(), DeepEquals, reflect.MakeMap(reflect.TypeOf(item)).Interface())
} else {
c.Assert(reflect.ValueOf(item).Elem().Interface(), DeepEquals, zero)
}
}
}
//var data []byte
//func init() {
// var err error
@@ -502,7 +703,7 @@ func (s *S) TestUnmarshalWithFalseSetterIgnoresValue(c *C) {
// var err error
// for i := 0; i < c.N; i++ {
// var v map[string]interface{}
// err = goyaml.Unmarshal(data, &v)
// err = yaml.Unmarshal(data, &v)
// }
// if err != nil {
// panic(err)
@@ -511,9 +712,9 @@ func (s *S) TestUnmarshalWithFalseSetterIgnoresValue(c *C) {
//
//func (s *S) BenchmarkMarshal(c *C) {
// var v map[string]interface{}
// goyaml.Unmarshal(data, &v)
// yaml.Unmarshal(data, &v)
// c.ResetTimer()
// for i := 0; i < c.N; i++ {
// goyaml.Marshal(&v)
// yaml.Marshal(&v)
// }
//}

View File

@@ -1,4 +1,4 @@
package goyaml
package yaml
import (
"bytes"
@@ -973,8 +973,8 @@ func yaml_emitter_analyze_tag(emitter *yaml_emitter_t, tag []byte) bool {
if bytes.HasPrefix(tag, tag_directive.prefix) {
emitter.tag_data.handle = tag_directive.handle
emitter.tag_data.suffix = tag[len(tag_directive.prefix):]
return true
}
return true
}
emitter.tag_data.suffix = tag
return true
@@ -1279,6 +1279,9 @@ func yaml_emitter_write_tag_content(emitter *yaml_emitter_t, value []byte, need_
for k := 0; k < w; k++ {
octet := value[i]
i++
if !put(emitter, '%') {
return false
}
c := octet >> 4
if c < 10 {

View File

@@ -1,9 +1,12 @@
package goyaml
package yaml
import (
"reflect"
"regexp"
"sort"
"strconv"
"strings"
"time"
)
type encoder struct {
@@ -49,14 +52,19 @@ func (e *encoder) must(ok bool) {
if msg == "" {
msg = "Unknown problem generating YAML content"
}
panic(msg)
fail(msg)
}
}
func (e *encoder) marshal(tag string, in reflect.Value) {
if !in.IsValid() {
e.nilv()
return
}
var value interface{}
if getter, ok := in.Interface().(Getter); ok {
tag, value = getter.GetYAML()
tag = longTag(tag)
if value == nil {
e.nilv()
return
@@ -85,7 +93,11 @@ func (e *encoder) marshal(tag string, in reflect.Value) {
case reflect.String:
e.stringv(tag, in)
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
e.intv(tag, in)
if in.Type() == durationType {
e.stringv(tag, reflect.ValueOf(in.Interface().(time.Duration).String()))
} else {
e.intv(tag, in)
}
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
e.uintv(tag, in)
case reflect.Float32, reflect.Float64:
@@ -93,7 +105,7 @@ func (e *encoder) marshal(tag string, in reflect.Value) {
case reflect.Bool:
e.boolv(tag, in)
default:
panic("Can't marshal type yet: " + in.Type().String())
panic("Can't marshal type: " + in.Type().String())
}
}
@@ -162,11 +174,46 @@ func (e *encoder) slicev(tag string, in reflect.Value) {
e.emit()
}
// isBase60 returns whether s is in base 60 notation as defined in YAML 1.1.
//
// The base 60 float notation in YAML 1.1 is a terrible idea and is unsupported
// in YAML 1.2 and by this package, but these should be marshalled quoted for
// the time being for compatibility with other parsers.
func isBase60Float(s string) (result bool) {
// Fast path.
if s == "" {
return false
}
c := s[0]
if !(c == '+' || c == '-' || c >= '0' && c <= '9') || strings.IndexByte(s, ':') < 0 {
return false
}
// Do the full match.
return base60float.MatchString(s)
}
// From http://yaml.org/type/float.html, except the regular expression there
// is bogus. In practice parsers do not enforce the "\.[0-9_]*" suffix.
var base60float = regexp.MustCompile(`^[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+(?:\.[0-9_]*)?$`)
func (e *encoder) stringv(tag string, in reflect.Value) {
var style yaml_scalar_style_t
s := in.String()
if rtag, _ := resolve("", s); rtag != "!!str" {
rtag, rs := resolve("", s)
if rtag == yaml_BINARY_TAG {
if tag == "" || tag == yaml_STR_TAG {
tag = rtag
s = rs.(string)
} else if tag == yaml_BINARY_TAG {
fail("explicitly tagged !!binary data must be base64-encoded")
} else {
fail("cannot marshal invalid UTF-8 data as " + shortTag(tag))
}
}
if tag == "" && (rtag != yaml_STR_TAG || isBase60Float(s)) {
style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
} else if strings.Contains(s, "\n") {
style = yaml_LITERAL_SCALAR_STYLE
} else {
style = yaml_PLAIN_SCALAR_STYLE
}
@@ -213,9 +260,6 @@ func (e *encoder) nilv() {
func (e *encoder) emitScalar(value, anchor, tag string, style yaml_scalar_style_t) {
implicit := tag == ""
if !implicit {
style = yaml_PLAIN_SCALAR_STYLE
}
e.must(yaml_scalar_event_initialize(&e.event, []byte(anchor), []byte(tag), []byte(value), implicit, implicit, style))
e.emit()
}

View File

@@ -1,12 +1,14 @@
package goyaml_test
package yaml_test
import (
"fmt"
. "launchpad.net/gocheck"
"github.com/coreos/coreos-cloudinit/third_party/launchpad.net/goyaml"
"math"
"strconv"
"strings"
"time"
"github.com/coreos/yaml"
. "gopkg.in/check.v1"
)
var marshalIntTest = 123
@@ -16,6 +18,9 @@ var marshalTests = []struct {
data string
}{
{
nil,
"null\n",
}, {
&struct{}{},
"{}\n",
}, {
@@ -86,7 +91,7 @@ var marshalTests = []struct {
"v:\n- A\n- B\n",
}, {
map[string][]string{"v": []string{"A", "B\nC"}},
"v:\n- A\n- 'B\n\n C'\n",
"v:\n- A\n- |-\n B\n C\n",
}, {
map[string][]interface{}{"v": []interface{}{"A", 1, map[string][]int{"B": []int{2, 3}}}},
"v:\n- A\n- 1\n- B:\n - 2\n - 3\n",
@@ -212,11 +217,51 @@ var marshalTests = []struct {
}{1, inlineB{2, inlineC{3}}},
"a: 1\nb: 2\nc: 3\n",
},
// Duration
{
map[string]time.Duration{"a": 3 * time.Second},
"a: 3s\n",
},
// Issue #24: bug in map merging logic.
{
map[string]string{"a": "<foo>"},
"a: <foo>\n",
},
// Issue #34: marshal unsupported base 60 floats quoted for compatibility
// with old YAML 1.1 parsers.
{
map[string]string{"a": "1:1"},
"a: \"1:1\"\n",
},
// Binary data.
{
map[string]string{"a": "\x00"},
"a: \"\\0\"\n",
}, {
map[string]string{"a": "\x80\x81\x82"},
"a: !!binary gIGC\n",
}, {
map[string]string{"a": strings.Repeat("\x90", 54)},
"a: !!binary |\n " + strings.Repeat("kJCQ", 17) + "kJ\n CQ\n",
}, {
map[string]interface{}{"a": typeWithGetter{"!!str", "\x80\x81\x82"}},
"a: !!binary gIGC\n",
},
// Escaping of tags.
{
map[string]interface{}{"a": typeWithGetter{"foo!bar", 1}},
"a: !<foo%21bar> 1\n",
},
}
func (s *S) TestMarshal(c *C) {
for _, item := range marshalTests {
data, err := goyaml.Marshal(item.value)
data, err := yaml.Marshal(item.value)
c.Assert(err, IsNil)
c.Assert(string(data), Equals, item.data)
}
@@ -225,20 +270,29 @@ func (s *S) TestMarshal(c *C) {
var marshalErrorTests = []struct {
value interface{}
error string
}{
{
&struct {
B int
inlineB ",inline"
}{1, inlineB{2, inlineC{3}}},
`Duplicated key 'b' in struct struct \{ B int; .*`,
},
}
panic string
}{{
value: &struct {
B int
inlineB ",inline"
}{1, inlineB{2, inlineC{3}}},
panic: `Duplicated key 'b' in struct struct \{ B int; .*`,
}, {
value: typeWithGetter{"!!binary", "\x80"},
error: "YAML error: explicitly tagged !!binary data must be base64-encoded",
}, {
value: typeWithGetter{"!!float", "\x80"},
error: `YAML error: cannot marshal invalid UTF-8 data as !!float`,
}}
func (s *S) TestMarshalErrors(c *C) {
for _, item := range marshalErrorTests {
_, err := goyaml.Marshal(item.value)
c.Assert(err, ErrorMatches, item.error)
if item.panic != "" {
c.Assert(func() { yaml.Marshal(item.value) }, PanicMatches, item.panic)
} else {
_, err := yaml.Marshal(item.value)
c.Assert(err, ErrorMatches, item.error)
}
}
}
@@ -269,12 +323,12 @@ func (s *S) TestMarshalTypeCache(c *C) {
var err error
func() {
type T struct{ A int }
data, err = goyaml.Marshal(&T{})
data, err = yaml.Marshal(&T{})
c.Assert(err, IsNil)
}()
func() {
type T struct{ B int }
data, err = goyaml.Marshal(&T{})
data, err = yaml.Marshal(&T{})
c.Assert(err, IsNil)
}()
c.Assert(string(data), Equals, "b: 0\n")
@@ -298,7 +352,7 @@ func (s *S) TestMashalWithGetter(c *C) {
obj := &typeWithGetterField{}
obj.Field.tag = item.tag
obj.Field.value = item.value
data, err := goyaml.Marshal(obj)
data, err := yaml.Marshal(obj)
c.Assert(err, IsNil)
c.Assert(string(data), Equals, string(item.data))
}
@@ -308,7 +362,7 @@ func (s *S) TestUnmarshalWholeDocumentWithGetter(c *C) {
obj := &typeWithGetter{}
obj.tag = ""
obj.value = map[string]string{"hello": "world!"}
data, err := goyaml.Marshal(obj)
data, err := yaml.Marshal(obj)
c.Assert(err, IsNil)
c.Assert(string(data), Equals, "hello: world!\n")
}
@@ -356,7 +410,7 @@ func (s *S) TestSortedOutput(c *C) {
for _, k := range order {
m[k] = 1
}
data, err := goyaml.Marshal(m)
data, err := yaml.Marshal(m)
c.Assert(err, IsNil)
out := "\n" + string(data)
last := 0

View File

@@ -1,4 +1,4 @@
package goyaml
package yaml
import (
"bytes"

View File

@@ -1,4 +1,4 @@
package goyaml
package yaml
import (
"io"

190
Godeps/_workspace/src/github.com/coreos/yaml/resolve.go generated vendored Normal file
View File

@@ -0,0 +1,190 @@
package yaml
import (
"encoding/base64"
"fmt"
"math"
"strconv"
"strings"
"unicode/utf8"
)
// TODO: merge, timestamps, base 60 floats, omap.
type resolveMapItem struct {
value interface{}
tag string
}
var resolveTable = make([]byte, 256)
var resolveMap = make(map[string]resolveMapItem)
func init() {
t := resolveTable
t[int('+')] = 'S' // Sign
t[int('-')] = 'S'
for _, c := range "0123456789" {
t[int(c)] = 'D' // Digit
}
for _, c := range "yYnNtTfFoO~" {
t[int(c)] = 'M' // In map
}
t[int('.')] = '.' // Float (potentially in map)
var resolveMapList = []struct {
v interface{}
tag string
l []string
}{
{true, yaml_BOOL_TAG, []string{"y", "Y", "yes", "Yes", "YES"}},
{true, yaml_BOOL_TAG, []string{"true", "True", "TRUE"}},
{true, yaml_BOOL_TAG, []string{"on", "On", "ON"}},
{false, yaml_BOOL_TAG, []string{"n", "N", "no", "No", "NO"}},
{false, yaml_BOOL_TAG, []string{"false", "False", "FALSE"}},
{false, yaml_BOOL_TAG, []string{"off", "Off", "OFF"}},
{nil, yaml_NULL_TAG, []string{"", "~", "null", "Null", "NULL"}},
{math.NaN(), yaml_FLOAT_TAG, []string{".nan", ".NaN", ".NAN"}},
{math.Inf(+1), yaml_FLOAT_TAG, []string{".inf", ".Inf", ".INF"}},
{math.Inf(+1), yaml_FLOAT_TAG, []string{"+.inf", "+.Inf", "+.INF"}},
{math.Inf(-1), yaml_FLOAT_TAG, []string{"-.inf", "-.Inf", "-.INF"}},
{"<<", yaml_MERGE_TAG, []string{"<<"}},
}
m := resolveMap
for _, item := range resolveMapList {
for _, s := range item.l {
m[s] = resolveMapItem{item.v, item.tag}
}
}
}
const longTagPrefix = "tag:yaml.org,2002:"
func shortTag(tag string) string {
// TODO This can easily be made faster and produce less garbage.
if strings.HasPrefix(tag, longTagPrefix) {
return "!!" + tag[len(longTagPrefix):]
}
return tag
}
func longTag(tag string) string {
if strings.HasPrefix(tag, "!!") {
return longTagPrefix + tag[2:]
}
return tag
}
func resolvableTag(tag string) bool {
switch tag {
case "", yaml_STR_TAG, yaml_BOOL_TAG, yaml_INT_TAG, yaml_FLOAT_TAG, yaml_NULL_TAG:
return true
}
return false
}
func resolve(tag string, in string) (rtag string, out interface{}) {
if !resolvableTag(tag) {
return tag, in
}
defer func() {
switch tag {
case "", rtag, yaml_STR_TAG, yaml_BINARY_TAG:
return
}
fail(fmt.Sprintf("cannot decode %s `%s` as a %s", shortTag(rtag), in, shortTag(tag)))
}()
// Any data is accepted as a !!str or !!binary.
// Otherwise, the prefix is enough of a hint about what it might be.
hint := byte('N')
if in != "" {
hint = resolveTable[in[0]]
}
if hint != 0 && tag != yaml_STR_TAG && tag != yaml_BINARY_TAG {
// Handle things we can lookup in a map.
if item, ok := resolveMap[in]; ok {
return item.tag, item.value
}
// Base 60 floats are a bad idea, were dropped in YAML 1.2, and
// are purposefully unsupported here. They're still quoted on
// the way out for compatibility with other parser, though.
switch hint {
case 'M':
// We've already checked the map above.
case '.':
// Not in the map, so maybe a normal float.
floatv, err := strconv.ParseFloat(in, 64)
if err == nil {
return yaml_FLOAT_TAG, floatv
}
case 'D', 'S':
// Int, float, or timestamp.
plain := strings.Replace(in, "_", "", -1)
intv, err := strconv.ParseInt(plain, 0, 64)
if err == nil {
if intv == int64(int(intv)) {
return yaml_INT_TAG, int(intv)
} else {
return yaml_INT_TAG, intv
}
}
floatv, err := strconv.ParseFloat(plain, 64)
if err == nil {
return yaml_FLOAT_TAG, floatv
}
if strings.HasPrefix(plain, "0b") {
intv, err := strconv.ParseInt(plain[2:], 2, 64)
if err == nil {
return yaml_INT_TAG, int(intv)
}
} else if strings.HasPrefix(plain, "-0b") {
intv, err := strconv.ParseInt(plain[3:], 2, 64)
if err == nil {
return yaml_INT_TAG, -int(intv)
}
}
// XXX Handle timestamps here.
default:
panic("resolveTable item not yet handled: " + string(rune(hint)) + " (with " + in + ")")
}
}
if tag == yaml_BINARY_TAG {
return yaml_BINARY_TAG, in
}
if utf8.ValidString(in) {
return yaml_STR_TAG, in
}
return yaml_BINARY_TAG, encodeBase64(in)
}
// encodeBase64 encodes s as base64 that is broken up into multiple lines
// as appropriate for the resulting length.
func encodeBase64(s string) string {
const lineLen = 70
encLen := base64.StdEncoding.EncodedLen(len(s))
lines := encLen/lineLen + 1
buf := make([]byte, encLen*2+lines)
in := buf[0:encLen]
out := buf[encLen:]
base64.StdEncoding.Encode(in, []byte(s))
k := 0
for i := 0; i < len(in); i += lineLen {
j := i + lineLen
if j > len(in) {
j = len(in)
}
k += copy(out[k:], in[i:j])
if lines > 1 {
out[k] = '\n'
k++
}
}
return string(out[:k])
}

View File

@@ -1,4 +1,4 @@
package goyaml
package yaml
import (
"bytes"

View File

@@ -1,4 +1,4 @@
package goyaml
package yaml
import (
"reflect"

View File

@@ -1,7 +1,7 @@
package goyaml_test
package yaml_test
import (
. "launchpad.net/gocheck"
. "gopkg.in/check.v1"
"testing"
)

View File

@@ -1,4 +1,4 @@
package goyaml
package yaml
// Set the writer error and return false.
func yaml_emitter_set_writer_error(emitter *yaml_emitter_t, problem string) bool {

View File

@@ -1,59 +1,60 @@
// Package goyaml implements YAML support for the Go language.
package goyaml
// Package yaml implements YAML support for the Go language.
//
// Source code and other details for the project are available at GitHub:
//
// https://github.com/go-yaml/yaml
//
package yaml
import (
"errors"
"fmt"
"reflect"
"runtime"
"strings"
"sync"
)
type yamlError string
func fail(msg string) {
panic(yamlError(msg))
}
func handleErr(err *error) {
if r := recover(); r != nil {
if _, ok := r.(runtime.Error); ok {
panic(r)
} else if _, ok := r.(*reflect.ValueError); ok {
panic(r)
} else if _, ok := r.(externalPanic); ok {
panic(r)
} else if s, ok := r.(string); ok {
*err = errors.New("YAML error: " + s)
} else if e, ok := r.(error); ok {
*err = e
if e, ok := r.(yamlError); ok {
*err = errors.New("YAML error: " + string(e))
} else {
panic(r)
}
}
}
// Objects implementing the goyaml.Setter interface will receive the YAML
// tag and value via the SetYAML method during unmarshaling, rather than
// being implicitly assigned by the goyaml machinery. If setting the value
// works, the method should return true. If it returns false, the given
// value will be omitted from maps and slices.
// The Setter interface may be implemented by types to do their own custom
// unmarshalling of YAML values, rather than being implicitly assigned by
// the yaml package machinery. If setting the value works, the method should
// return true. If it returns false, the value is considered unsupported
// and is omitted from maps and slices.
type Setter interface {
SetYAML(tag string, value interface{}) bool
}
// Objects implementing the goyaml.Getter interface will get the GetYAML()
// method called when goyaml is requested to marshal the given value, and
// the result of this method will be marshaled in place of the actual object.
// The Getter interface is implemented by types to do their own custom
// marshalling into a YAML tag and value.
type Getter interface {
GetYAML() (tag string, value interface{})
}
// Unmarshal decodes the first document found within the in byte slice
// and assigns decoded values into the object pointed by out.
// and assigns decoded values into the out value.
//
// Maps, pointers to structs and ints, etc, may all be used as out values.
// If an internal pointer within a struct is not initialized, goyaml
// will initialize it if necessary for unmarshalling the provided data,
// but the struct provided as out must not be a nil pointer.
// Maps and pointers (to a struct, string, int, etc) are accepted as out
// values. If an internal pointer within a struct is not initialized,
// the yaml package will initialize it if necessary for unmarshalling
// the provided data. The out parameter must not be nil.
//
// The type of the decoded values and the type of out will be considered,
// and Unmarshal() will do the best possible job to unmarshal values
// and Unmarshal will do the best possible job to unmarshal values
// appropriately. It is NOT considered an error, though, to skip values
// because they are not available in the decoded YAML, or if they are not
// compatible with the out value. To ensure something was properly
@@ -61,11 +62,11 @@ type Getter interface {
// field (usually the zero value).
//
// Struct fields are only unmarshalled if they are exported (have an
// upper case first letter), and will be unmarshalled using the field
// name lowercased by default. When custom field names are desired, the
// tag value may be used to tweak the name. Everything before the first
// comma in the field tag will be used as the name. The values following
// the comma are used to tweak the marshalling process (see Marshal).
// upper case first letter), and are unmarshalled using the field name
// lowercased as the default key. Custom keys may be defined via the
// "yaml" name in the field tag: the content preceding the first comma
// is used as the key, and the following comma-separated options are
// used to tweak the marshalling process (see Marshal).
// Conflicting names result in a runtime error.
//
// For example:
@@ -74,8 +75,8 @@ type Getter interface {
// F int `yaml:"a,omitempty"`
// B int
// }
// var T t
// goyaml.Unmarshal([]byte("a: 1\nb: 2"), &t)
// var t T
// yaml.Unmarshal([]byte("a: 1\nb: 2"), &t)
//
// See the documentation of Marshal for the format of tags and a list of
// supported tag options.
@@ -83,25 +84,31 @@ type Getter interface {
func Unmarshal(in []byte, out interface{}) (err error) {
defer handleErr(&err)
d := newDecoder()
p := newParser(in)
p := newParser(in, UnmarshalMappingKeyTransform)
defer p.destroy()
node := p.parse()
if node != nil {
d.unmarshal(node, reflect.ValueOf(out))
v := reflect.ValueOf(out)
if v.Kind() == reflect.Ptr && !v.IsNil() {
v = v.Elem()
}
d.unmarshal(node, v)
}
return nil
}
// Marshal serializes the value provided into a YAML document. The structure
// of the generated document will reflect the structure of the value itself.
// Maps, pointers to structs and ints, etc, may all be used as the in value.
// Maps and pointers (to struct, string, int, etc) are accepted as the in value.
//
// In the case of struct values, only exported fields will be serialized.
// The lowercased field name is used as the key for each exported field,
// but this behavior may be changed using the respective field tag.
// The tag may also contain flags to tweak the marshalling behavior for
// the field. Conflicting names result in a runtime error. The tag format
// accepted is:
// Struct fields are only unmarshalled if they are exported (have an upper case
// first letter), and are unmarshalled using the field name lowercased as the
// default key. Custom keys may be defined via the "yaml" name in the field
// tag: the content preceding the first comma is used as the key, and the
// following comma-separated options are used to tweak the marshalling process.
// Conflicting names result in a runtime error.
//
// The field tag format accepted is:
//
// `(...) yaml:"[<key>][,<flag1>[,<flag2>]]" (...)`
//
@@ -126,8 +133,8 @@ func Unmarshal(in []byte, out interface{}) (err error) {
// F int "a,omitempty"
// B int
// }
// goyaml.Marshal(&T{B: 2}) // Returns "b: 2\n"
// goyaml.Marshal(&T{F: 1}} // Returns "a: 1\nb: 0\n"
// yaml.Marshal(&T{B: 2}) // Returns "b: 2\n"
// yaml.Marshal(&T{F: 1}} // Returns "a: 1\nb: 0\n"
//
func Marshal(in interface{}) (out []byte, err error) {
defer handleErr(&err)
@@ -139,10 +146,21 @@ func Marshal(in interface{}) (out []byte, err error) {
return
}
// UnmarshalMappingKeyTransform is a string transformation that is applied to
// each mapping key in a YAML document before it is unmarshalled. By default,
// UnmarshalMappingKeyTransform is an identity transform (no modification).
var UnmarshalMappingKeyTransform transformString = identityTransform
type transformString func(in string) (out string)
func identityTransform(in string) (out string) {
return in
}
// --------------------------------------------------------------------------
// Maintain a mapping of keys to structure field indexes
// The code in this section was copied from gobson.
// The code in this section was copied from mgo/bson.
// structInfo holds details for the serialization of fields of
// a given struct.
@@ -168,12 +186,6 @@ type fieldInfo struct {
var structMap = make(map[reflect.Type]*structInfo)
var fieldMapMutex sync.RWMutex
type externalPanic string
func (e externalPanic) String() string {
return string(e)
}
func getStructInfo(st reflect.Type) (*structInfo, error) {
fieldMapMutex.RLock()
sinfo, found := structMap[st]
@@ -214,8 +226,7 @@ func getStructInfo(st reflect.Type) (*structInfo, error) {
case "inline":
inline = true
default:
msg := fmt.Sprintf("Unsupported flag %q in tag %q of type %s", flag, tag, st)
panic(externalPanic(msg))
return nil, errors.New(fmt.Sprintf("Unsupported flag %q in tag %q of type %s", flag, tag, st))
}
}
tag = fields[0]
@@ -223,6 +234,7 @@ func getStructInfo(st reflect.Type) (*structInfo, error) {
if inline {
switch field.Type.Kind() {
// TODO: Implement support for inline maps.
//case reflect.Map:
// if inlineMap >= 0 {
// return nil, errors.New("Multiple ,inline maps in struct " + st.String())
@@ -250,8 +262,8 @@ func getStructInfo(st reflect.Type) (*structInfo, error) {
fieldsList = append(fieldsList, finfo)
}
default:
//panic("Option ,inline needs a struct value or map field")
panic("Option ,inline needs a struct value field")
//return nil, errors.New("Option ,inline needs a struct value or map field")
return nil, errors.New("Option ,inline needs a struct value field")
}
continue
}

View File

@@ -1,4 +1,4 @@
package goyaml
package yaml
import (
"io"
@@ -294,6 +294,10 @@ const (
yaml_SEQ_TAG = "tag:yaml.org,2002:seq" // The tag !!seq is used to denote sequences.
yaml_MAP_TAG = "tag:yaml.org,2002:map" // The tag !!map is used to denote mapping.
// Not in original libyaml.
yaml_BINARY_TAG = "tag:yaml.org,2002:binary"
yaml_MERGE_TAG = "tag:yaml.org,2002:merge"
yaml_DEFAULT_SCALAR_TAG = yaml_STR_TAG // The default scalar tag is !!str.
yaml_DEFAULT_SEQUENCE_TAG = yaml_SEQ_TAG // The default sequence tag is !!seq.
yaml_DEFAULT_MAPPING_TAG = yaml_MAP_TAG // The default mapping tag is !!map.

View File

@@ -1,4 +1,4 @@
package goyaml
package yaml
const (
// The size of the input raw buffer.

View File

@@ -2,7 +2,7 @@ package introspect
import (
"encoding/xml"
"github.com/coreos/coreos-cloudinit/third_party/github.com/guelfey/go.dbus"
"github.com/coreos/coreos-cloudinit/Godeps/_workspace/src/github.com/guelfey/go.dbus"
"strings"
)

View File

@@ -2,7 +2,7 @@ package introspect
import (
"encoding/xml"
"github.com/coreos/coreos-cloudinit/third_party/github.com/guelfey/go.dbus"
"github.com/coreos/coreos-cloudinit/Godeps/_workspace/src/github.com/guelfey/go.dbus"
"reflect"
)

View File

@@ -3,8 +3,8 @@
package prop
import (
"github.com/coreos/coreos-cloudinit/third_party/github.com/guelfey/go.dbus"
"github.com/coreos/coreos-cloudinit/third_party/github.com/guelfey/go.dbus/introspect"
"github.com/coreos/coreos-cloudinit/Godeps/_workspace/src/github.com/guelfey/go.dbus"
"github.com/coreos/coreos-cloudinit/Godeps/_workspace/src/github.com/guelfey/go.dbus/introspect"
"sync"
)

View File

@@ -0,0 +1,502 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 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.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
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 and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, 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 library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete 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 distribute a copy of this License along with the
Library.
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 Library or any portion
of it, thus forming a work based on the Library, 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) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
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 Library, 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 Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you 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.
If distribution of 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 satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be 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.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library 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.
9. 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 Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
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 with
this License.
11. 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 Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library 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 Library.
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.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library 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.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser 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 Library
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 Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
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
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "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
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. 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 LIBRARY 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
LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), 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 Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. 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 library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; 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.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

View File

@@ -0,0 +1,272 @@
/*********************************************************
* Copyright (C) 1999-2015 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
*********************************************************/
/*********************************************************
* The contents of this file are subject to the terms of the Common
* Development and Distribution License (the "License") version 1.0
* and no later version. You may not use this file except in
* compliance with the License.
*
* You can obtain a copy of the License at
* http://www.opensource.org/licenses/cddl1.php
*
* See the License for the specific language governing permissions
* and limitations under the License.
*
*********************************************************/
/*
* backdoor.c --
*
* First layer of the internal communication channel between guest
* applications and vmware
*
* This is the backdoor. By using special ports of the virtual I/O space,
* and the virtual CPU registers, a guest application can send a
* synchroneous basic request to vmware, and vmware can reply to it.
*/
#ifdef __cplusplus
extern "C" {
#endif
#include "backdoor_def.h"
#include "backdoor.h"
#include "backdoorInt.h"
#if defined(BACKDOOR_DEBUG) && defined(USERLEVEL)
#if defined(__KERNEL__) || defined(_KERNEL)
#else
# include "debug.h"
#endif
# include <stdio.h>
# define BACKDOOR_LOG(args) Debug args
# define BACKDOOR_LOG_PROTO_STRUCT(x) BackdoorPrintProtoStruct((x))
# define BACKDOOR_LOG_HB_PROTO_STRUCT(x) BackdoorPrintHbProtoStruct((x))
/*
*----------------------------------------------------------------------------
*
* BackdoorPrintProtoStruct --
* BackdoorPrintHbProtoStruct --
*
* Print the contents of the specified backdoor protocol structure via
* printf.
*
* Results:
* None.
*
* Side effects:
* Output to stdout.
*
*----------------------------------------------------------------------------
*/
void
BackdoorPrintProtoStruct(Backdoor_proto *myBp)
{
Debug("magic 0x%08x, command %d, size %"FMTSZ"u, port %d\n",
myBp->in.ax.word, myBp->in.cx.halfs.low,
myBp->in.size, myBp->in.dx.halfs.low);
#ifndef VM_X86_64
Debug("ax %#x, "
"bx %#x, "
"cx %#x, "
"dx %#x, "
"si %#x, "
"di %#x\n",
myBp->out.ax.word,
myBp->out.bx.word,
myBp->out.cx.word,
myBp->out.dx.word,
myBp->out.si.word,
myBp->out.di.word);
#else
Debug("ax %#"FMT64"x, "
"bx %#"FMT64"x, "
"cx %#"FMT64"x, "
"dx %#"FMT64"x, "
"si %#"FMT64"x, "
"di %#"FMT64"x\n",
myBp->out.ax.quad,
myBp->out.bx.quad,
myBp->out.cx.quad,
myBp->out.dx.quad,
myBp->out.si.quad,
myBp->out.di.quad);
#endif
}
void
BackdoorPrintHbProtoStruct(Backdoor_proto_hb *myBp)
{
Debug("magic 0x%08x, command %d, size %"FMTSZ"u, port %d, "
"srcAddr %"FMTSZ"u, dstAddr %"FMTSZ"u\n",
myBp->in.ax.word, myBp->in.bx.halfs.low, myBp->in.size,
myBp->in.dx.halfs.low, myBp->in.srcAddr, myBp->in.dstAddr);
#ifndef VM_X86_64
Debug("ax %#x, "
"bx %#x, "
"cx %#x, "
"dx %#x, "
"si %#x, "
"di %#x, "
"bp %#x\n",
myBp->out.ax.word,
myBp->out.bx.word,
myBp->out.cx.word,
myBp->out.dx.word,
myBp->out.si.word,
myBp->out.di.word,
myBp->out.bp.word);
#else
Debug("ax %#"FMT64"x, "
"bx %#"FMT64"x, "
"cx %#"FMT64"x, "
"dx %#"FMT64"x, "
"si %#"FMT64"x, "
"di %#"FMT64"x, "
"bp %#"FMT64"x\n",
myBp->out.ax.quad,
myBp->out.bx.quad,
myBp->out.cx.quad,
myBp->out.dx.quad,
myBp->out.si.quad,
myBp->out.di.quad,
myBp->out.bp.quad);
#endif
}
#else
# define BACKDOOR_LOG(args)
# define BACKDOOR_LOG_PROTO_STRUCT(x)
# define BACKDOOR_LOG_HB_PROTO_STRUCT(x)
#endif
/*
*-----------------------------------------------------------------------------
*
* Backdoor --
*
* Send a low-bandwidth basic request (16 bytes) to vmware, and return its
* reply (24 bytes).
*
* Result:
* None
*
* Side-effects:
* None
*
*-----------------------------------------------------------------------------
*/
void
Backdoor(Backdoor_proto *myBp) // IN/OUT
{
ASSERT(myBp);
myBp->in.ax.word = BDOOR_MAGIC;
myBp->in.dx.halfs.low = BDOOR_PORT;
BACKDOOR_LOG(("Backdoor: before "));
BACKDOOR_LOG_PROTO_STRUCT(myBp);
Backdoor_InOut(myBp);
BACKDOOR_LOG(("Backdoor: after "));
BACKDOOR_LOG_PROTO_STRUCT(myBp);
}
/*
*-----------------------------------------------------------------------------
*
* Backdoor_HbOut --
*
* Send a high-bandwidth basic request to vmware, and return its
* reply.
*
* Result:
* The host-side response is returned via the IN/OUT parameter.
*
* Side-effects:
* Pokes the high-bandwidth backdoor.
*
*-----------------------------------------------------------------------------
*/
void
Backdoor_HbOut(Backdoor_proto_hb *myBp) // IN/OUT
{
ASSERT(myBp);
myBp->in.ax.word = BDOOR_MAGIC;
myBp->in.dx.halfs.low = BDOORHB_PORT;
BACKDOOR_LOG(("Backdoor_HbOut: before "));
BACKDOOR_LOG_HB_PROTO_STRUCT(myBp);
BackdoorHbOut(myBp);
BACKDOOR_LOG(("Backdoor_HbOut: after "));
BACKDOOR_LOG_HB_PROTO_STRUCT(myBp);
}
/*
*-----------------------------------------------------------------------------
*
* Backdoor_HbIn --
*
* Send a basic request to vmware, and return its high-bandwidth
* reply
*
* Result:
* Host-side response returned via the IN/OUT parameter.
*
* Side-effects:
* Pokes the high-bandwidth backdoor.
*
*-----------------------------------------------------------------------------
*/
void
Backdoor_HbIn(Backdoor_proto_hb *myBp) // IN/OUT
{
ASSERT(myBp);
myBp->in.ax.word = BDOOR_MAGIC;
myBp->in.dx.halfs.low = BDOORHB_PORT;
BACKDOOR_LOG(("Backdoor_HbIn: before "));
BACKDOOR_LOG_HB_PROTO_STRUCT(myBp);
BackdoorHbIn(myBp);
BACKDOOR_LOG(("Backdoor_HbIn: after "));
BACKDOOR_LOG_HB_PROTO_STRUCT(myBp);
}
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,235 @@
/*********************************************************
* Copyright (C) 2005-2015 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
*********************************************************/
/*********************************************************
* The contents of this file are subject to the terms of the Common
* Development and Distribution License (the "License") version 1.0
* and no later version. You may not use this file except in
* compliance with the License.
*
* You can obtain a copy of the License at
* http://www.opensource.org/licenses/cddl1.php
*
* See the License for the specific language governing permissions
* and limitations under the License.
*
*********************************************************/
/*
* backdoorGcc32.c --
*
* Implements the real work for guest-side backdoor for GCC, 32-bit
* target (supports inline ASM, GAS syntax). The asm sections are marked
* volatile since vmware can change the registers content without the
* compiler knowing it.
*
* XXX
* I tried to write this more cleanly, but:
* - There is no way to specify an "ebp" constraint
* - "ebp" is ignored when specified as cloberred register
* - gas barfs when there is more than 10 operands
* - gas 2.7.2.3, depending on the order of the operands, can
* mis-assemble without any warning
* --hpreg
*
* Note that the problems with gas noted above might longer be relevant
* now that we've upgraded most of our compiler versions.
* --rrdharan
*/
#ifdef __cplusplus
extern "C" {
#endif
#include "backdoor.h"
#include "backdoorInt.h"
/*
*----------------------------------------------------------------------------
*
* Backdoor_InOut --
*
* Send a low-bandwidth basic request (16 bytes) to vmware, and return its
* reply (24 bytes).
*
* Results:
* Host-side response returned in bp IN/OUT parameter.
*
* Side effects:
* Pokes the backdoor.
*
*----------------------------------------------------------------------------
*/
void
Backdoor_InOut(Backdoor_proto *myBp) // IN/OUT
{
uint32 dummy;
__asm__ __volatile__(
#ifdef __PIC__
"pushl %%ebx" "\n\t"
#endif
"pushl %%eax" "\n\t"
"movl 20(%%eax), %%edi" "\n\t"
"movl 16(%%eax), %%esi" "\n\t"
"movl 12(%%eax), %%edx" "\n\t"
"movl 8(%%eax), %%ecx" "\n\t"
"movl 4(%%eax), %%ebx" "\n\t"
"movl (%%eax), %%eax" "\n\t"
"inl %%dx, %%eax" "\n\t"
"xchgl %%eax, (%%esp)" "\n\t"
"movl %%edi, 20(%%eax)" "\n\t"
"movl %%esi, 16(%%eax)" "\n\t"
"movl %%edx, 12(%%eax)" "\n\t"
"movl %%ecx, 8(%%eax)" "\n\t"
"movl %%ebx, 4(%%eax)" "\n\t"
"popl (%%eax)" "\n\t"
#ifdef __PIC__
"popl %%ebx" "\n\t"
#endif
: "=a" (dummy)
: "0" (myBp)
/*
* vmware can modify the whole VM state without the compiler knowing
* it. So far it does not modify EFLAGS. --hpreg
*/
:
#ifndef __PIC__
"ebx",
#endif
"ecx", "edx", "esi", "edi", "memory"
);
}
/*
*-----------------------------------------------------------------------------
*
* BackdoorHbIn --
* BackdoorHbOut --
*
* Send a high-bandwidth basic request to vmware, and return its
* reply.
*
* Results:
* Host-side response returned in bp IN/OUT parameter.
*
* Side-effects:
* Pokes the high-bandwidth backdoor port.
*
*-----------------------------------------------------------------------------
*/
void
BackdoorHbIn(Backdoor_proto_hb *myBp) // IN/OUT
{
uint32 dummy;
__asm__ __volatile__(
#ifdef __PIC__
"pushl %%ebx" "\n\t"
#endif
"pushl %%ebp" "\n\t"
"pushl %%eax" "\n\t"
"movl 24(%%eax), %%ebp" "\n\t"
"movl 20(%%eax), %%edi" "\n\t"
"movl 16(%%eax), %%esi" "\n\t"
"movl 12(%%eax), %%edx" "\n\t"
"movl 8(%%eax), %%ecx" "\n\t"
"movl 4(%%eax), %%ebx" "\n\t"
"movl (%%eax), %%eax" "\n\t"
"cld" "\n\t"
"rep; insb" "\n\t"
"xchgl %%eax, (%%esp)" "\n\t"
"movl %%ebp, 24(%%eax)" "\n\t"
"movl %%edi, 20(%%eax)" "\n\t"
"movl %%esi, 16(%%eax)" "\n\t"
"movl %%edx, 12(%%eax)" "\n\t"
"movl %%ecx, 8(%%eax)" "\n\t"
"movl %%ebx, 4(%%eax)" "\n\t"
"popl (%%eax)" "\n\t"
"popl %%ebp" "\n\t"
#ifdef __PIC__
"popl %%ebx" "\n\t"
#endif
: "=a" (dummy)
: "0" (myBp)
/*
* vmware can modify the whole VM state without the compiler knowing
* it. --hpreg
*/
:
#ifndef __PIC__
"ebx",
#endif
"ecx", "edx", "esi", "edi", "memory", "cc"
);
}
void
BackdoorHbOut(Backdoor_proto_hb *myBp) // IN/OUT
{
uint32 dummy;
__asm__ __volatile__(
#ifdef __PIC__
"pushl %%ebx" "\n\t"
#endif
"pushl %%ebp" "\n\t"
"pushl %%eax" "\n\t"
"movl 24(%%eax), %%ebp" "\n\t"
"movl 20(%%eax), %%edi" "\n\t"
"movl 16(%%eax), %%esi" "\n\t"
"movl 12(%%eax), %%edx" "\n\t"
"movl 8(%%eax), %%ecx" "\n\t"
"movl 4(%%eax), %%ebx" "\n\t"
"movl (%%eax), %%eax" "\n\t"
"cld" "\n\t"
"rep; outsb" "\n\t"
"xchgl %%eax, (%%esp)" "\n\t"
"movl %%ebp, 24(%%eax)" "\n\t"
"movl %%edi, 20(%%eax)" "\n\t"
"movl %%esi, 16(%%eax)" "\n\t"
"movl %%edx, 12(%%eax)" "\n\t"
"movl %%ecx, 8(%%eax)" "\n\t"
"movl %%ebx, 4(%%eax)" "\n\t"
"popl (%%eax)" "\n\t"
"popl %%ebp" "\n\t"
#ifdef __PIC__
"popl %%ebx" "\n\t"
#endif
: "=a" (dummy)
: "0" (myBp)
:
#ifndef __PIC__
"ebx",
#endif
"ecx", "edx", "esi", "edi", "memory", "cc"
);
}
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,243 @@
/*********************************************************
* Copyright (C) 2005-2015 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
*********************************************************/
/*********************************************************
* The contents of this file are subject to the terms of the Common
* Development and Distribution License (the "License") version 1.0
* and no later version. You may not use this file except in
* compliance with the License.
*
* You can obtain a copy of the License at
* http://www.opensource.org/licenses/cddl1.php
*
* See the License for the specific language governing permissions
* and limitations under the License.
*
*********************************************************/
/*
* backdoorGcc64.c --
*
* Implements the real work for guest-side backdoor for GCC, 64-bit
* target (supports inline ASM, GAS syntax). The asm sections are marked
* volatile since vmware can change the registers content without the
* compiler knowing it.
*
* See backdoorGCC32.c (from which this code was mostly copied) for
* details on why the ASM is written this way. Also note that it might be
* possible to write the asm blocks using the symbolic operand specifiers
* in such a way that the same asm would generate correct code for both
* 32-bit and 64-bit targets, but I'm too lazy to figure it all out.
* --rrdharan
*/
#ifdef __cplusplus
extern "C" {
#endif
#include "backdoor.h"
#include "backdoorInt.h"
/*
*----------------------------------------------------------------------------
*
* Backdoor_InOut --
*
* Send a low-bandwidth basic request (16 bytes) to vmware, and return its
* reply (24 bytes).
*
* Results:
* Host-side response returned in bp IN/OUT parameter.
*
* Side effects:
* Pokes the backdoor.
*
*----------------------------------------------------------------------------
*/
void
Backdoor_InOut(Backdoor_proto *myBp) // IN/OUT
{
uint64 dummy;
__asm__ __volatile__(
#ifdef __APPLE__
/*
* Save %rbx on the stack because the Mac OS GCC doesn't want us to
* clobber it - it erroneously thinks %rbx is the PIC register.
* (Radar bug 7304232)
*/
"pushq %%rbx" "\n\t"
#endif
"pushq %%rax" "\n\t"
"movq 40(%%rax), %%rdi" "\n\t"
"movq 32(%%rax), %%rsi" "\n\t"
"movq 24(%%rax), %%rdx" "\n\t"
"movq 16(%%rax), %%rcx" "\n\t"
"movq 8(%%rax), %%rbx" "\n\t"
"movq (%%rax), %%rax" "\n\t"
"inl %%dx, %%eax" "\n\t" /* NB: There is no inq instruction */
"xchgq %%rax, (%%rsp)" "\n\t"
"movq %%rdi, 40(%%rax)" "\n\t"
"movq %%rsi, 32(%%rax)" "\n\t"
"movq %%rdx, 24(%%rax)" "\n\t"
"movq %%rcx, 16(%%rax)" "\n\t"
"movq %%rbx, 8(%%rax)" "\n\t"
"popq (%%rax)" "\n\t"
#ifdef __APPLE__
"popq %%rbx" "\n\t"
#endif
: "=a" (dummy)
: "0" (myBp)
/*
* vmware can modify the whole VM state without the compiler knowing
* it. So far it does not modify EFLAGS. --hpreg
*/
:
#ifndef __APPLE__
/* %rbx is unchanged at the end of the function on Mac OS. */
"rbx",
#endif
"rcx", "rdx", "rsi", "rdi", "memory"
);
}
/*
*-----------------------------------------------------------------------------
*
* BackdoorHbIn --
* BackdoorHbOut --
*
* Send a high-bandwidth basic request to vmware, and return its
* reply.
*
* Results:
* Host-side response returned in bp IN/OUT parameter.
*
* Side-effects:
* Pokes the high-bandwidth backdoor port.
*
*-----------------------------------------------------------------------------
*/
void
BackdoorHbIn(Backdoor_proto_hb *myBp) // IN/OUT
{
uint64 dummy;
__asm__ __volatile__(
"pushq %%rbp" "\n\t"
#ifdef __APPLE__
/*
* Save %rbx on the stack because the Mac OS GCC doesn't want us to
* clobber it - it erroneously thinks %rbx is the PIC register.
* (Radar bug 7304232)
*/
"pushq %%rbx" "\n\t"
#endif
"pushq %%rax" "\n\t"
"movq 48(%%rax), %%rbp" "\n\t"
"movq 40(%%rax), %%rdi" "\n\t"
"movq 32(%%rax), %%rsi" "\n\t"
"movq 24(%%rax), %%rdx" "\n\t"
"movq 16(%%rax), %%rcx" "\n\t"
"movq 8(%%rax), %%rbx" "\n\t"
"movq (%%rax), %%rax" "\n\t"
"cld" "\n\t"
"rep; insb" "\n\t"
"xchgq %%rax, (%%rsp)" "\n\t"
"movq %%rbp, 48(%%rax)" "\n\t"
"movq %%rdi, 40(%%rax)" "\n\t"
"movq %%rsi, 32(%%rax)" "\n\t"
"movq %%rdx, 24(%%rax)" "\n\t"
"movq %%rcx, 16(%%rax)" "\n\t"
"movq %%rbx, 8(%%rax)" "\n\t"
"popq (%%rax)" "\n\t"
#ifdef __APPLE__
"popq %%rbx" "\n\t"
#endif
"popq %%rbp"
: "=a" (dummy)
: "0" (myBp)
/*
* vmware can modify the whole VM state without the compiler knowing
* it. --hpreg
*/
:
#ifndef __APPLE__
/* %rbx is unchanged at the end of the function on Mac OS. */
"rbx",
#endif
"rcx", "rdx", "rsi", "rdi", "memory", "cc"
);
}
void
BackdoorHbOut(Backdoor_proto_hb *myBp) // IN/OUT
{
uint64 dummy;
__asm__ __volatile__(
"pushq %%rbp" "\n\t"
#ifdef __APPLE__
/*
* Save %rbx on the stack because the Mac OS GCC doesn't want us to
* clobber it - it erroneously thinks %rbx is the PIC register.
* (Radar bug 7304232)
*/
"pushq %%rbx" "\n\t"
#endif
"pushq %%rax" "\n\t"
"movq 48(%%rax), %%rbp" "\n\t"
"movq 40(%%rax), %%rdi" "\n\t"
"movq 32(%%rax), %%rsi" "\n\t"
"movq 24(%%rax), %%rdx" "\n\t"
"movq 16(%%rax), %%rcx" "\n\t"
"movq 8(%%rax), %%rbx" "\n\t"
"movq (%%rax), %%rax" "\n\t"
"cld" "\n\t"
"rep; outsb" "\n\t"
"xchgq %%rax, (%%rsp)" "\n\t"
"movq %%rbp, 48(%%rax)" "\n\t"
"movq %%rdi, 40(%%rax)" "\n\t"
"movq %%rsi, 32(%%rax)" "\n\t"
"movq %%rdx, 24(%%rax)" "\n\t"
"movq %%rcx, 16(%%rax)" "\n\t"
"movq %%rbx, 8(%%rax)" "\n\t"
"popq (%%rax)" "\n\t"
#ifdef __APPLE__
"popq %%rbx" "\n\t"
#endif
"popq %%rbp"
: "=a" (dummy)
: "0" (myBp)
:
#ifndef __APPLE__
/* %rbx is unchanged at the end of the function on Mac OS. */
"rbx",
#endif
"rcx", "rdx", "rsi", "rdi", "memory", "cc"
);
}
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,60 @@
package bridge
/*
#cgo CFLAGS: -I../include
#include <stdlib.h>
#include "message.h"
#include "vmcheck.h"
void Warning(const char *fmt, ...) {}
void Debug(const char *fmt, ...) {}
void Panic(const char *fmt, ...) {}
void Log(const char *fmt, ...) {}
*/
import "C"
import "unsafe"
// MessageChannel provides a channel to pass information from/to the hypervisor
type MessageChannel *C.struct_Message_Channel
// MessageOpen creates a new MessageChannel
func MessageOpen(proto uint32) MessageChannel {
return C.Message_Open(C.uint32(proto))
}
// MessageClose closes a MessageChannel
func MessageClose(c MessageChannel) bool {
status := C.Message_Close(c)
return status != 0
}
// MessageSend sends a request through a MessageChannel
func MessageSend(c MessageChannel, request []byte) bool {
buffer := (*C.uchar)(unsafe.Pointer(&request[0]))
status := C.Message_Send(c, buffer, (C.size_t)(C.int(len(request))))
return status != 0
}
// MessageReceive receives a response through a MessageChannel
func MessageReceive(c MessageChannel) ([]byte, bool) {
var reply *C.uchar
var replyLen C.size_t
defer C.free(unsafe.Pointer(reply))
status := C.Message_Receive(c, &reply, &replyLen)
res := C.GoBytes(unsafe.Pointer(reply), (C.int)(replyLen))
return res, status != 0
}
// VMCheckIsVirtualWorld checks if current code is running in a VMware virtual machine
func VMCheckIsVirtualWorld() bool {
return C.VmCheck_IsVirtualWorld() != 0
}
// VMCheckGetVersion returns the identifiers of the current hypervisor
func VMCheckGetVersion() (uint32, uint32) {
var version C.uint32
var typ C.uint32
C.VmCheck_GetVersion(&version, &typ)
return uint32(version), uint32(typ)
}

View File

@@ -0,0 +1,439 @@
/*********************************************************
* Copyright (C) 1998-2015 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
*********************************************************/
/*
* dynbuf.c --
*
* Dynamic buffers --hpreg
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "vmware.h"
#include "dynbuf.h"
/*
*-----------------------------------------------------------------------------
*
* DynBuf_Init --
*
* Dynamic buffer constructor --hpreg
*
* Results:
* None
*
* Side effects:
* None
*
*-----------------------------------------------------------------------------
*/
void
DynBuf_Init(DynBuf *b) // OUT:
{
ASSERT(b);
b->data = NULL;
b->size = 0;
b->allocated = 0;
}
/*
*-----------------------------------------------------------------------------
*
* DynBuf_Destroy --
*
* Dynamic buffer destructor --hpreg
*
* Results:
* None
*
* Side effects:
* None
*
*-----------------------------------------------------------------------------
*/
void
DynBuf_Destroy(DynBuf *b) // IN/OUT:
{
ASSERT(b);
free(b->data);
DynBuf_Init(b);
}
/*
*-----------------------------------------------------------------------------
*
* DynBuf_AllocGet --
*
* Retrieve a pointer to the data contained in a dynamic buffer. Return
* a copy of that data.
*
* Results:
* The pointer to the data. NULL on out of memory failure.
*
* Side effects:
* Allocates memory.
*
*-----------------------------------------------------------------------------
*/
void *
DynBuf_AllocGet(DynBuf const *b) // IN
{
void *new_data;
ASSERT(b);
new_data = malloc(b->size);
if (new_data) {
memcpy(new_data, b->data, b->size);
}
return new_data;
}
/*
*-----------------------------------------------------------------------------
*
* DynBuf_Attach --
*
* Grants ownership of the specified buffer to the DynBuf
* object. If there is an existing buffer, it is freed.
*
* Results:
* None.
*
* Side effects:
* None
*
*-----------------------------------------------------------------------------
*/
void
DynBuf_Attach(DynBuf *b, // IN
size_t size, // IN
void *data) // IN
{
ASSERT(b);
ASSERT((size == 0) == (data == NULL));
free(b->data);
b->data = data;
b->size = b->allocated = size;
}
/*
*-----------------------------------------------------------------------------
*
* DynBuf_Detach --
*
* Releases ownership of the buffer stored in the DynBuf object,
* and returns a pointer to it.
*
* Results:
* The pointer to the data.
*
* Side effects:
* None
*
*-----------------------------------------------------------------------------
*/
void *
DynBuf_Detach(DynBuf *b) // IN
{
void *data;
ASSERT(b);
data = b->data;
b->data = NULL;
b->allocated = 0;
return data;
}
/*
*-----------------------------------------------------------------------------
*
* DynBufRealloc --
*
* Reallocate a dynamic buffer --hpreg
*
* Results:
* TRUE on success
* FALSE on failure (not enough memory)
*
* Side effects:
* None
*
*-----------------------------------------------------------------------------
*/
static Bool
DynBufRealloc(DynBuf *b, // IN:
size_t newAllocated) // IN:
{
void *new_data;
ASSERT(b);
new_data = realloc(b->data, newAllocated);
if (new_data == NULL && newAllocated) {
/* Not enough memory */
return FALSE;
}
b->data = new_data;
b->allocated = newAllocated;
return TRUE;
}
/*
*-----------------------------------------------------------------------------
*
* DynBuf_Enlarge --
*
* Enlarge a dynamic buffer. The resulting dynamic buffer is guaranteed to
* be larger than the one you passed, and at least 'minSize' bytes
* large --hpreg
*
* Results:
* TRUE on success
* FALSE on failure (not enough memory)
*
* Side effects:
* None
*
*-----------------------------------------------------------------------------
*/
Bool
DynBuf_Enlarge(DynBuf *b, // IN:
size_t minSize) // IN:
{
size_t newAllocated;
ASSERT(b);
newAllocated = b->allocated
?
#if defined(DYNBUF_DEBUG)
b->allocated + 1
#else
/*
* Double the previously allocated size if it is less
* than 256KB; otherwise grow it linearly by 256KB
*/
(b->allocated < 256 * 1024 ? b->allocated * 2
: b->allocated + 256 * 1024)
#endif
:
#if defined(DYNBUF_DEBUG)
1
#else
/*
* Initial size: 1 KB. Most buffers are smaller than
* that --hpreg
*/
1 << 10
#endif
;
if (minSize > newAllocated) {
newAllocated = minSize;
}
/*
* Prevent integer overflow. We can use this form of checking specifically
* because a multiple by 2 is used (in the worst case). This type of
* checking does not work in the general case.
*/
if (newAllocated < b->allocated) {
return FALSE;
}
return DynBufRealloc(b, newAllocated);
}
/*
*-----------------------------------------------------------------------------
*
* DynBuf_Append --
*
* Append data at the end of a dynamic buffer. 'size' is the size of the
* data. If it is <= 0, no operation is performed --hpreg
*
* Results:
* TRUE on success
* FALSE on failure (not enough memory)
*
* Side effects:
* None
*
*-----------------------------------------------------------------------------
*/
Bool
DynBuf_Append(DynBuf *b, // IN
void const *data, // IN
size_t size) // IN
{
size_t new_size;
ASSERT(b);
if (size <= 0) {
return TRUE;
}
ASSERT(data);
new_size = b->size + size;
if (new_size < b->size) { // Prevent integer overflow
return FALSE;
}
if (new_size > b->allocated) {
/* Not enough room */
if (DynBuf_Enlarge(b, new_size) == FALSE) {
return FALSE;
}
}
memcpy(b->data + b->size, data, size);
b->size = new_size;
return TRUE;
}
/*
*-----------------------------------------------------------------------------
*
* DynBuf_SafeInternalAppend --
*
* Append data at the end of a dynamic buffer. Memory allocation failure
* are handled the same way as Util_SafeMalloc, that is to say, with a
* Panic.
*
* Results:
* None
*
* Side effects:
* None
*
*-----------------------------------------------------------------------------
*/
void
DynBuf_SafeInternalAppend(DynBuf *b, // IN
void const *data, // IN
size_t size, // IN
char const *file, // IN
unsigned int lineno) // IN
{
if (!DynBuf_Append(b, data, size)) {
Panic("Unrecoverable memory allocation failure at %s:%u\n",
file, lineno);
}
}
/*
*-----------------------------------------------------------------------------
*
* DynBuf_Trim --
*
* Reallocate a dynamic buffer to the exact size it occupies --hpreg
*
* Results:
* TRUE on success
* FALSE on failure (not enough memory)
*
* Side effects:
* None
*
*-----------------------------------------------------------------------------
*/
Bool
DynBuf_Trim(DynBuf *b) // IN
{
ASSERT(b);
return DynBufRealloc(b, b->size);
}
/*
*-----------------------------------------------------------------------------
*
* DynBuf_Copy --
*
* Copies all data and metadata from src dynbuff to dest dynbuf.
*
* Dest should be an initialized DynBuf of alloced length zero
* to prevent memory leaks.
*
* Results:
* TRUE on success, FALSE on failure.
*
* Side effects:
* None
*
*-----------------------------------------------------------------------------
*/
Bool
DynBuf_Copy(DynBuf *src, // IN
DynBuf *dest) // OUT
{
ASSERT(src);
ASSERT(dest);
ASSERT(!dest->data);
dest->data = malloc(src->allocated);
if (dest->data == NULL) {
return FALSE;
}
dest->size = src->size;
dest->allocated = src->allocated;
memcpy(dest->data, src->data, src->size);
return TRUE;
}

View File

@@ -0,0 +1,336 @@
/*********************************************************
* Copyright (C) 1998-2015 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
*********************************************************/
/*
* hostinfo.c --
*
* Platform-independent code that calls into hostinfo<OS>-specific
* code.
*/
#include "vmware.h"
#include <string.h>
#if defined(__i386__) || defined(__x86_64__)
#include "cpuid_info.h"
#endif
#include "hostinfo.h"
#include "hostinfoInt.h"
#include "util.h"
/* #include "str.h" */
#include <stdio.h>
#define Str_Sprintf snprintf
#include "dynbuf.h"
#include "backdoor_def.h"
/*
* #define LOGLEVEL_MODULE hostinfo
* #include "loglevel_user.h"
*/
#define LGPFX "HOSTINFO:"
/*
* HostinfoOSData caches its returned value.
*/
volatile Bool HostinfoOSNameCacheValid = FALSE;
char HostinfoCachedOSName[MAX_OS_NAME_LEN];
char HostinfoCachedOSFullName[MAX_OS_FULLNAME_LEN];
#if defined(__i386__) || defined(__x86_64__)
/*
*-----------------------------------------------------------------------------
*
* HostInfoGetCpuidStrSection --
*
* Append a section (either low or high) of CPUID as a string in DynBuf.
* E.g.
* 00000000:00000005756E65476C65746E49656E69-
* 00000001:00000F4A000208000000649DBFEBFBFF-
* or
* 80000000:80000008000000000000000000000000-
* 80000001:00000000000000000000000120100000-
* 80000008:00003024000000000000000000000000-
*
* The returned eax of args[0] is used to determine the upper bound for
* the following input arguments. And the input args should be in
* ascending order.
*
* Results:
* None. The string will be appended in buf.
*
* Side effect:
* None
*
*-----------------------------------------------------------------------------
*/
static void
HostInfoGetCpuidStrSection(const uint32 args[], // IN: input eax arguments
const size_t args_size, // IN: size of the argument array
DynBuf *buf) // IN/OUT: result string in DynBuf
{
static const char format[] = "%08X:%08X%08X%08X%08X-";
CPUIDRegs reg;
uint32 max_arg;
char temp[64];
int i;
__GET_CPUID(args[0], &reg);
max_arg = reg.eax;
if (max_arg < args[0]) {
Warning(LGPFX" No CPUID information available. Based = %08X.\n",
args[0]);
return;
}
DynBuf_Append(buf, temp,
Str_Sprintf(temp, sizeof temp, format, args[0], reg.eax,
reg.ebx, reg.ecx, reg.edx));
for (i = 1; i < args_size && args[i] <= max_arg; i++) {
ASSERT(args[i] > args[i - 1]); // Ascending order.
__GET_CPUID(args[i], &reg);
DynBuf_Append(buf, temp,
Str_Sprintf(temp, sizeof temp, format, args[i], reg.eax,
reg.ebx, reg.ecx, reg.edx));
}
}
/*
*-----------------------------------------------------------------------------
*
* Hostinfo_GetCpuidStr --
*
* Get the basic and extended CPUID as a string. E.g.
* 00000000:00000005756E65476C65746E49656E69-
* 00000001:00000F4A000208000000649DBFEBFBFF-
* 80000000:80000008000000000000000000000000-
* 80000001:00000000000000000000000120100000-
* 80000008:00003024000000000000000000000000
*
* If the extended CPUID is not available, only returns the basic CPUID.
*
* Results:
* The CPUID string if the processor supports the CPUID instruction and
* this is a processor we recognize. It should never fail, since it
* would at least return leaf 0. Caller needs to free the returned string.
*
* Side effect:
* None
*
*-----------------------------------------------------------------------------
*/
char *
Hostinfo_GetCpuidStr(void)
{
static const uint32 basic_args[] = {0x0, 0x1, 0xa};
static const uint32 extended_args[] = {0x80000000, 0x80000001, 0x80000008};
DynBuf buf;
char *result;
DynBuf_Init(&buf);
HostInfoGetCpuidStrSection(basic_args, ARRAYSIZE(basic_args), &buf);
HostInfoGetCpuidStrSection(extended_args, ARRAYSIZE(extended_args), &buf);
// Trim buffer and set NULL character to replace last '-'.
DynBuf_Trim(&buf);
result = (char*)DynBuf_Get(&buf);
ASSERT(result && result[0]); // We should at least get result from eax = 0x0.
result[DynBuf_GetSize(&buf) - 1] = '\0';
return DynBuf_Detach(&buf);
}
#endif // defined(__i386__) || defined(__x86_64__)
/*
*-----------------------------------------------------------------------------
*
* Hostinfo_GetCpuid --
*
* Get cpuid information for a CPU. Which CPU the information is for
* depends on the OS scheduler. We are assuming that all CPUs in
* the system have identical numbers of cores and threads.
*
* Results:
* TRUE if the processor supports the cpuid instruction and this
* is a process we recognize, FALSE otherwise.
*
* Side effect:
* None
*
*-----------------------------------------------------------------------------
*/
Bool
Hostinfo_GetCpuid(HostinfoCpuIdInfo *info) // OUT
{
#if defined(__i386__) || defined(__x86_64__)
CPUIDSummary cpuid;
CPUIDRegs id0;
/*
* Can't do cpuid = {0} as an initializer above because gcc throws
* some idiotic warning.
*/
memset(&cpuid, 0, sizeof(cpuid));
/*
* Get basic and extended CPUID info.
*/
__GET_CPUID(0, &id0);
cpuid.id0.numEntries = id0.eax;
if (0 == cpuid.id0.numEntries) {
Warning(LGPFX" No CPUID information available.\n");
return FALSE;
}
*(uint32*)(cpuid.id0.name + 0) = id0.ebx;
*(uint32*)(cpuid.id0.name + 4) = id0.edx;
*(uint32*)(cpuid.id0.name + 8) = id0.ecx;
*(uint32*)(cpuid.id0.name + 12) = 0;
__GET_CPUID(1, (CPUIDRegs*)&cpuid.id1);
__GET_CPUID(0xa, (CPUIDRegs*)&cpuid.ida);
__GET_CPUID(0x80000000, (CPUIDRegs*)&cpuid.id80);
__GET_CPUID(0x80000001, (CPUIDRegs*)&cpuid.id81);
__GET_CPUID(0x80000008, (CPUIDRegs*)&cpuid.id88);
/*
* Calculate vendor information.
*/
if (0 == strcmp(cpuid.id0.name, CPUID_INTEL_VENDOR_STRING_FIXED)) {
info->vendor = CPUID_VENDOR_INTEL;
} else if (strcmp(cpuid.id0.name, CPUID_AMD_VENDOR_STRING_FIXED) == 0) {
info->vendor = CPUID_VENDOR_AMD;
} else {
info->vendor = CPUID_VENDOR_UNKNOWN;
}
/*
* Pull out versioning and feature information.
*/
info->version = cpuid.id1.version;
info->family = CPUID_GET(1, EAX, FAMILY, cpuid.id1.version);
info->model = CPUID_GET(1, EAX, MODEL, cpuid.id1.version);
info->stepping = CPUID_GET(1, EAX, STEPPING, cpuid.id1.version);
info->type = (cpuid.id1.version >> 12) & 0x0003;
info->extfeatures = cpuid.id1.ecxFeatures;
info->features = cpuid.id1.edxFeatures;
return TRUE;
#else // defined(__i386__) || defined(__x86_64__)
return FALSE;
#endif // defined(__i386__) || defined(__x86_64__)
}
/*
*-----------------------------------------------------------------------------
*
* Hostinfo_GetOSName --
*
* Query the operating system and build a string to identify it.
*
* Examples:
* Windows: <OS NAME> <SERVICE PACK> (Build <BUILD_NUMBER>)
* example: Windows XP Professional Service Pack 2 (Build 2600)
*
* Linux: <OS NAME> <OS RELEASE> <SPECIFIC_DISTRO_INFO>
* example: Linux 2.4.18-3 Red Hat Linux release 7.3 (Valhalla)
*
* Mac OS: <OS NAME> <OS VERSION> (<BUILD VERSION>) <KERNEL NAME> <KERNEL RELEASE>
* example: Mac OS X 10.8.5 (12F45) Darwin 12.5.0
*
* Return value:
* NULL Unable to obtain the OS name.
* !NULL The OS name. The caller is responsible for freeing it.
*
* Side effects:
* Memory is allocated.
*
*-----------------------------------------------------------------------------
*/
/*
* char *
* Hostinfo_GetOSName(void)
* {
* char *name;
* Bool data = HostinfoOSNameCacheValid ? TRUE : HostinfoOSData();
*
* if (data) {
* name = Util_SafeStrdup(HostinfoCachedOSFullName);
* } else {
* name = NULL;
* }
*
* return name;
* }
*/
/*
*-----------------------------------------------------------------------------
*
* Hostinfo_GetOSGuestString --
*
* Query the operating system and build a string to identify it. The
* returned string is the same as you'd see in a VM's .vmx file.
*
* Return value:
* NULL Unable to obtain the OS name.
* !NULL The OS name. The caller is responsible for freeing it.
*
* Side effects:
* Memory is allocated.
*
*-----------------------------------------------------------------------------
*/
/*
* char *
* Hostinfo_GetOSGuestString(void)
* {
* char *name;
* Bool data = HostinfoOSNameCacheValid ? TRUE : HostinfoOSData();
*
* if (data) {
* name = Util_SafeStrdup(HostinfoCachedOSName);
* } else {
* name = NULL;
* }
*
* return name;
* }
*/

View File

@@ -0,0 +1,686 @@
/*********************************************************
* Copyright (C) 2011-2015 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
*********************************************************/
/*
* hostinfoHV.c --
*
* Code to detect different hypervisors and features.
*/
#include <string.h>
#include "vmware.h"
#if defined(__i386__) || defined(__x86_64__)
# include "cpuid_info.h"
# include "backdoor_def.h"
# include "backdoor_types.h"
#endif
#include "hostinfo.h"
#include "util.h"
#define LGPFX "HOSTINFO:"
/*
* #define LOGLEVEL_MODULE hostinfo
* #include "loglevel_user.h"
*/
/*
*----------------------------------------------------------------------
*
* Hostinfo_HypervisorCPUIDSig --
*
* Get the hypervisor signature string from CPUID.
*
* Results:
* Unqualified 16 byte nul-terminated hypervisor string
* String may contain garbage and caller must free
*
* Side effects:
* None
*
*----------------------------------------------------------------------
*/
char *
Hostinfo_HypervisorCPUIDSig(void)
{
uint32 *name = NULL;
#if defined(__i386__) || defined(__x86_64__)
CPUIDRegs regs;
__GET_CPUID(1, &regs);
if (!CPUID_ISSET(1, ECX, HYPERVISOR, regs.ecx)) {
return NULL;
}
regs.ebx = 0;
regs.ecx = 0;
regs.edx = 0;
__GET_CPUID(0x40000000, &regs);
if (regs.eax < 0x40000000) {
Log(LGPFX" CPUID hypervisor bit is set, but no "
"hypervisor vendor signature is present\n");
}
name = Util_SafeMalloc(4 * sizeof *name);
name[0] = regs.ebx;
name[1] = regs.ecx;
name[2] = regs.edx;
name[3] = 0;
#endif // defined(__i386__) || defined(__x86_64__)
return (char *)name;
}
/*
*----------------------------------------------------------------------
*
* Hostinfo_TouchXen --
*
* Check for Xen.
*
* Official way is to call Hostinfo_HypervisorCPUIDSig(), which
* returns a hypervisor string. This is a secondary check
* that guards against a backdoor failure. See PR156185,
* http://xenbits.xensource.com/xen-unstable.hg?file/6a383beedf83/tools/misc/xen-detect.c
* (Canonical way is /proc/xen, but CPUID is better).
*
* Results:
* TRUE if we are running in a Xen dom0 or domU.
* Linux:
* Illegal instruction exception on real hardware.
* Obscure Xen implementations might return FALSE.
* Windows:
* FALSE on real hardware.
*
* Side effects:
* Linux: Will raise exception on native hardware.
* Windows: None.
*
*----------------------------------------------------------------------
*/
Bool
Hostinfo_TouchXen(void)
{
#if defined(linux) && (defined(__i386__) || defined(__x86_64__))
#define XEN_CPUID 0x40000000
CPUIDRegs regs;
uint32 name[4];
/*
* PV mode: ud2a "xen" cpuid (faults on native hardware).
* (Only Linux can run PV, so skip others here).
* Since PV cannot trap CPUID, this is a Xen hook.
*/
regs.eax = XEN_CPUID;
__asm__ __volatile__(
"xchgl %%ebx, %0" "\n\t"
"ud2a ; .ascii \"xen\" ; cpuid" "\n\t"
"xchgl %%ebx, %0"
: "=&r" (regs.ebx), "=&c" (regs.ecx), "=&d" (regs.edx)
: "a" (regs.eax)
);
name[0] = regs.ebx;
name[1] = regs.ecx;
name[2] = regs.edx;
name[3] = 0;
if (0 == strcmp(CPUID_XEN_HYPERVISOR_VENDOR_STRING, (const char*)name)) {
return TRUE;
}
/* Passed checks. But native and anything non-Xen would #UD before here. */
NOT_TESTED();
Log("Xen detected but hypervisor unrecognized (Xen variant?)\n");
Log("CPUID 0x4000 0000: eax=%x ebx=%x ecx=%x edx=%x\n",
regs.eax, regs.ebx, regs.ecx, regs.edx);
#endif
return FALSE;
}
/*
*----------------------------------------------------------------------
*
* Hostinfo_SLC64Supported --
*
* Access the backdoor with an SLC64 control query. This is used
* to determine if we are running in a VM that supports SLC64.
* This function should only be called after determining that the
* backdoor is present with Hostinfo_TouchBackdoor().
*
* Results:
* TRUE if the outer VM supports SLC64.
* FALSE otherwise.
*
* Side effects:
* Exception if not in a VM, so don't do that!
*
*----------------------------------------------------------------------
*/
Bool
Hostinfo_SLC64Supported(void)
{
#if defined(__i386__) || defined(__x86_64__)
return Hostinfo_VCPUInfoBackdoor(BDOOR_CMD_VCPU_SLC64);
#else
return FALSE;
#endif
}
/*
*----------------------------------------------------------------------
*
* Hostinfo_NestedHVReplaySupported --
*
* Access the backdoor with a HV replay control query. This is used
* to determine if we are running in a VM that supports nested HV replay.
* This function should only be called after determining that the
* backdoor is present with Hostinfo_TouchBackdoor().
*
* Results:
* TRUE if the outer VM supports nexted HV replay.
* FALSE otherwise.
*
* Side effects:
* Exception if not in a VM, so don't do that!
*
*----------------------------------------------------------------------
*/
Bool
Hostinfo_NestedHVReplaySupported(void)
{
#if defined(__i386__) || defined(__x86_64__)
return Hostinfo_VCPUInfoBackdoor(BDOOR_CMD_VCPU_HV_REPLAY_OK);
#else
return FALSE;
#endif
}
/*
*----------------------------------------------------------------------
*
* Hostinfo_SynchronizedVTSCs --
*
* Access the backdoor to determine if the VCPUs' TSCs are
* synchronized.
*
* Results:
* TRUE if the outer VM provides synchronized VTSCs.
* FALSE otherwise.
*
* Side effects:
* Exception if not in a VM, so don't do that!
*
*----------------------------------------------------------------------
*/
Bool
Hostinfo_SynchronizedVTSCs(void)
{
#if defined(__i386__) || defined(__x86_64__)
return Hostinfo_VCPUInfoBackdoor(BDOOR_CMD_VCPU_SYNC_VTSCS);
#else
return FALSE;
#endif
}
#if defined(_WIN32)
#if defined(_WIN64)
// from touchBackdoorMasm64.asm
void Hostinfo_BackdoorInOut(Backdoor_proto *myBp);
#endif
/*
*----------------------------------------------------------------------
*
* Hostinfo_TouchBackDoor --
*
* Access the backdoor. This is used to determine if we are
* running in a VM or on a physical host. On a physical host
* this should generate a GP which we catch and thereby determine
* that we are not in a VM. However some OSes do not handle the
* GP correctly and the process continues running returning garbage.
* In this case we check the EBX register which should be
* BDOOR_MAGIC if the IN was handled in a VM. Based on this we
* return either TRUE or FALSE.
*
* Results:
* TRUE if we succesfully accessed the backdoor, FALSE or segfault
* if not.
*
* Side effects:
* Exception if not in a VM.
*
*----------------------------------------------------------------------
*/
Bool
Hostinfo_TouchBackDoor(void)
{
uint32 ebxval;
#if defined(_WIN64)
Backdoor_proto bp;
bp.in.ax.quad = BDOOR_MAGIC;
bp.in.size = ~BDOOR_MAGIC;
bp.in.cx.quad = BDOOR_CMD_GETVERSION;
bp.in.dx.quad = BDOOR_PORT;
Hostinfo_BackdoorInOut(&bp);
ebxval = bp.out.bx.words.low;
#else // _WIN64
_asm {
push edx
push ecx
push ebx
mov ecx, BDOOR_CMD_GETVERSION
mov ebx, ~BDOOR_MAGIC
mov eax, BDOOR_MAGIC
mov dx, BDOOR_PORT
in eax, dx
mov ebxval, ebx
pop ebx
pop ecx
pop edx
}
#endif // _WIN64
return (ebxval == BDOOR_MAGIC) ? TRUE : FALSE;
}
/*
*----------------------------------------------------------------------
*
* Hostinfo_TouchVirtualPC --
*
* Access MS Virtual PC's backdoor. This is used to determine if
* we are running in a MS Virtual PC or on a physical host. Works
* the same as Hostinfo_TouchBackDoor, except the entry to MS VPC
* is an invalid opcode instead or writing to a port. Since
* MS VPC is 32-bit only, the WIN64 path returns FALSE.
* See: See: http://www.codeproject.com/KB/system/VmDetect.aspx
*
* Results:
* TRUE if we succesfully accessed MS Virtual PC, FALSE or
* segfault if not.
*
* Side effects:
* Exception if not in a VM.
*
*----------------------------------------------------------------------
*/
Bool
Hostinfo_TouchVirtualPC(void)
{
#if defined(_WIN64)
return FALSE; // MS Virtual PC is 32-bit only
#else // _WIN32
uint32 ebxval;
_asm {
push ebx
mov ebx, 0
mov eax, 1 // Virtual PC function number
// execute invalid opcode to call into MS Virtual PC
__emit 0Fh
__emit 3Fh
__emit 07h
__emit 0Bh
mov ebxval, ebx
pop ebx
}
return !ebxval; // ebx is zero if inside Virtual PC
#endif
}
/*
*----------------------------------------------------------------------
*
* Hostinfo_NestingSupported --
*
* Access the backdoor with a nesting control query. This is used
* to determine if we are running in a VM that supports nesting.
* This function should only be called after determining that the
* backdoor is present with Hostinfo_TouchBackdoor().
*
* Results:
* TRUE if the outer VM supports nesting.
* FALSE otherwise.
*
* Side effects:
* Exception if not in a VM, so don't do that!
*
*----------------------------------------------------------------------
*/
Bool
Hostinfo_NestingSupported(void)
{
uint32 cmd = NESTING_CONTROL_QUERY << 16 | BDOOR_CMD_NESTING_CONTROL;
uint32 result;
#if defined(_WIN64)
Backdoor_proto bp;
bp.in.ax.quad = BDOOR_MAGIC;
bp.in.cx.quad = cmd;
bp.in.dx.quad = BDOOR_PORT;
Hostinfo_BackdoorInOut(&bp);
result = bp.out.ax.words.low;
#else
_asm {
push edx
push ecx
mov ecx, cmd
mov eax, BDOOR_MAGIC
mov dx, BDOOR_PORT
in eax, dx
mov result, eax
pop ecx
pop edx
}
#endif
if (result >= NESTING_CONTROL_QUERY && result != ~0U) {
return TRUE;
}
return FALSE;
}
/*
*----------------------------------------------------------------------
*
* Hostinfo_VCPUInfoBackdoor --
*
* Access the backdoor with an VCPU info query. This is used to
* determine whether a VCPU supports a particular feature,
* determined by 'bit'. This function should only be called after
* determining that the backdoor is present with
* Hostinfo_TouchBackdoor().
*
* Results:
* TRUE if the outer VM supports the feature.
* FALSE otherwise.
*
* Side effects:
* Exception if not in a VM, so don't do that!
*
*----------------------------------------------------------------------
*/
Bool
Hostinfo_VCPUInfoBackdoor(unsigned bit)
{
uint32 cmd = BDOOR_CMD_GET_VCPU_INFO;
uint32 result;
#if defined(_WIN64)
Backdoor_proto bp;
bp.in.ax.quad = BDOOR_MAGIC;
bp.in.cx.quad = cmd;
bp.in.dx.quad = BDOOR_PORT;
Hostinfo_BackdoorInOut(&bp);
result = bp.out.ax.words.low;
#else
_asm {
push edx
push ecx
mov ecx, cmd
mov eax, BDOOR_MAGIC
mov dx, BDOOR_PORT
in eax, dx
mov result, eax
pop ecx
pop edx
}
#endif
/* If reserved bit is 1, this command wasn't implemented. */
return (result & (1 << BDOOR_CMD_VCPU_RESERVED)) == 0 &&
(result & (1 << bit)) != 0;
}
#else
/*
*----------------------------------------------------------------------
*
* Hostinfo_TouchBackDoor --
*
* Access the backdoor. This is used to determine if we are
* running in a VM or on a physical host. On a physical host
* this should generate a GP which we catch and thereby determine
* that we are not in a VM. However some OSes do not handle the
* GP correctly and the process continues running returning garbage.
* In this case we check the EBX register which should be
* BDOOR_MAGIC if the IN was handled in a VM. Based on this we
* return either TRUE or FALSE.
*
* Results:
* TRUE if we succesfully accessed the backdoor, FALSE or segfault
* if not.
*
* Side effects:
* Exception if not in a VM.
*
*----------------------------------------------------------------------
*/
Bool
Hostinfo_TouchBackDoor(void)
{
#if defined(__i386__) || defined(__x86_64__)
uint32 eax;
uint32 ebx;
uint32 ecx;
__asm__ __volatile__(
# if defined __PIC__ && !vm_x86_64 // %ebx is reserved by the compiler.
"xchgl %%ebx, %1" "\n\t"
"inl %%dx, %%eax" "\n\t"
"xchgl %%ebx, %1"
: "=a" (eax),
"=&rm" (ebx),
# else
"inl %%dx, %%eax"
: "=a" (eax),
"=b" (ebx),
# endif
"=c" (ecx)
: "0" (BDOOR_MAGIC),
"1" (~BDOOR_MAGIC),
"2" (BDOOR_CMD_GETVERSION),
"d" (BDOOR_PORT)
);
if (ebx == BDOOR_MAGIC) {
return TRUE;
}
#endif
return FALSE;
}
/*
*----------------------------------------------------------------------
*
* Hostinfo_TouchVirtualPC --
*
* Access MS Virtual PC's backdoor. This is used to determine if
* we are running in a MS Virtual PC or on a physical host. Works
* the same as Hostinfo_TouchBackDoor, except the entry to MS VPC
* is an invalid opcode instead or writing to a port. Since
* MS VPC is 32-bit only, the 64-bit path returns FALSE.
* See: http://www.codeproject.com/KB/system/VmDetect.aspx
*
* Results:
* TRUE if we succesfully accessed MS Virtual PC, FALSE or
* segfault if not.
*
* Side effects:
* Exception if not in a VM.
*
*----------------------------------------------------------------------
*/
Bool
Hostinfo_TouchVirtualPC(void)
{
#if defined vm_x86_64
return FALSE;
#else
uint32 ebxval;
__asm__ __volatile__ (
# if defined __PIC__ // %ebx is reserved by the compiler.
"xchgl %%ebx, %1" "\n\t"
".long 0x0B073F0F" "\n\t"
"xchgl %%ebx, %1"
: "=&rm" (ebxval)
: "a" (1),
"0" (0)
# else
".long 0x0B073F0F"
: "=b" (ebxval)
: "a" (1),
"b" (0)
# endif
);
return !ebxval; // %%ebx is zero if inside Virtual PC
#endif
}
/*
*----------------------------------------------------------------------
*
* Hostinfo_NestingSupported --
*
* Access the backdoor with a nesting control query. This is used
* to determine if we are running inside a VM that supports nesting.
* This function should only be called after determining that the
* backdoor is present with Hostinfo_TouchBackdoor().
*
* Results:
* TRUE if the outer VM supports nesting.
* FALSE otherwise.
*
* Side effects:
* Exception if not in a VM, so don't do that!
*
*----------------------------------------------------------------------
*/
Bool
Hostinfo_NestingSupported(void)
{
#if defined(__i386__) || defined(__x86_64__)
uint32 cmd = NESTING_CONTROL_QUERY << 16 | BDOOR_CMD_NESTING_CONTROL;
uint32 result;
__asm__ __volatile__(
"inl %%dx, %%eax"
: "=a" (result)
: "0" (BDOOR_MAGIC),
"c" (cmd),
"d" (BDOOR_PORT)
);
if (result >= NESTING_CONTROL_QUERY && result != ~0U) {
return TRUE;
}
#endif
return FALSE;
}
/*
*----------------------------------------------------------------------
*
* Hostinfo_VCPUInfoBackdoor --
*
* Access the backdoor with an VCPU info query. This is used to
* determine whether a VCPU supports a particular feature,
* determined by 'bit'. This function should only be called after
* determining that the backdoor is present with
* Hostinfo_TouchBackdoor().
*
* Results:
* TRUE if the outer VM supports the feature.
* FALSE otherwise.
*
* Side effects:
* Exception if not in a VM, so don't do that!
*
*----------------------------------------------------------------------
*/
Bool
Hostinfo_VCPUInfoBackdoor(unsigned bit)
{
#if defined(__i386__) || defined(__x86_64__)
uint32 result;
__asm__ __volatile__(
"inl %%dx, %%eax"
: "=a" (result)
: "0" (BDOOR_MAGIC),
"c" (BDOOR_CMD_GET_VCPU_INFO),
"d" (BDOOR_PORT)
);
/* If reserved bit is 1, this command wasn't implemented. */
return (result & (1 << BDOOR_CMD_VCPU_RESERVED)) == 0 &&
(result & (1 << bit)) != 0;
#endif
return FALSE;
}
#endif

View File

@@ -0,0 +1,605 @@
/*********************************************************
* Copyright (C) 1999-2015 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
*********************************************************/
/*********************************************************
* The contents of this file are subject to the terms of the Common
* Development and Distribution License (the "License") version 1.0
* and no later version. You may not use this file except in
* compliance with the License.
*
* You can obtain a copy of the License at
* http://www.opensource.org/licenses/cddl1.php
*
* See the License for the specific language governing permissions
* and limitations under the License.
*
*********************************************************/
/*
* message.c --
*
* Second layer of the internal communication channel between guest
* applications and vmware
*
* Build a generic messaging system between guest applications and vmware.
*
* The protocol is not completely symmetrical, because:
* . basic requests can only be sent by guest applications (when vmware
* wants to post a message to a guest application, the message will be
* really fetched only when the guest application will poll for new
* available messages)
* . several guest applications can talk to vmware, while the contrary is
* not true
*
* Operations that are not atomic (in terms of number of backdoor calls)
* can be aborted by vmware if a checkpoint/restore occurs in the middle of
* such an operation. This layer takes care of retrying those operations.
*/
#ifdef __cplusplus
extern "C" {
#endif
#if defined(__KERNEL__) || defined(_KERNEL) || defined(KERNEL)
# include "kernelStubs.h"
#else
# include <stdio.h>
# include <stdlib.h>
# include "debug.h"
#endif
#include "backdoor_def.h"
#include "guest_msg_def.h"
#include "backdoor.h"
#include "message.h"
#if defined(MESSAGE_DEBUG)
# define MESSAGE_LOG(...) Warning(__VA_ARGS__)
#else
# define MESSAGE_LOG(...)
#endif
/* The channel object */
struct Message_Channel {
/* Identifier */
uint16 id;
/* Reception buffer */
/* Data */
unsigned char *in;
/* Allocated size */
size_t inAlloc;
/* The cookie */
uint32 cookieHigh;
uint32 cookieLow;
};
/*
*-----------------------------------------------------------------------------
*
* Message_Open --
*
* Open a communication channel
*
* Result:
* An allocated Message_Channel on success
* NULL on failure
*
* Side-effects:
* None
*
*-----------------------------------------------------------------------------
*/
Message_Channel *
Message_Open(uint32 proto) // IN
{
Message_Channel *chan;
uint32 flags;
Backdoor_proto bp;
chan = (Message_Channel *)malloc(sizeof(*chan));
if (chan == NULL) {
goto error_quit;
}
flags = GUESTMSG_FLAG_COOKIE;
retry:
/* IN: Type */
bp.in.cx.halfs.high = MESSAGE_TYPE_OPEN;
/* IN: Magic number of the protocol and flags */
bp.in.size = proto | flags;
bp.in.cx.halfs.low = BDOOR_CMD_MESSAGE;
Backdoor(&bp);
/* OUT: Status */
if ((bp.in.cx.halfs.high & MESSAGE_STATUS_SUCCESS) == 0) {
if (flags) {
/* Cookies not supported. Fall back to no cookie. --hpreg */
flags = 0;
goto retry;
}
MESSAGE_LOG("Message: Unable to open a communication channel\n");
goto error_quit;
}
/* OUT: Id and cookie */
chan->id = bp.in.dx.halfs.high;
chan->cookieHigh = bp.out.si.word;
chan->cookieLow = bp.out.di.word;
/* Initialize the channel */
chan->in = NULL;
chan->inAlloc = 0;
return chan;
error_quit:
free(chan);
chan = NULL;
return NULL;
}
/*
*-----------------------------------------------------------------------------
*
* Message_Send --
*
* Send a message over a communication channel
*
* Result:
* TRUE on success
* FALSE on failure (the message is discarded by vmware)
*
* Side-effects:
* None
*
*-----------------------------------------------------------------------------
*/
Bool
Message_Send(Message_Channel *chan, // IN/OUT
const unsigned char *buf, // IN
size_t bufSize) // IN
{
const unsigned char *myBuf;
size_t myBufSize;
Backdoor_proto bp;
retry:
myBuf = buf;
myBufSize = bufSize;
/*
* Send the size.
*/
/* IN: Type */
bp.in.cx.halfs.high = MESSAGE_TYPE_SENDSIZE;
/* IN: Id and cookie */
bp.in.dx.halfs.high = chan->id;
bp.in.si.word = chan->cookieHigh;
bp.in.di.word = chan->cookieLow;
/* IN: Size */
bp.in.size = myBufSize;
bp.in.cx.halfs.low = BDOOR_CMD_MESSAGE;
Backdoor(&bp);
/* OUT: Status */
if ((bp.in.cx.halfs.high & MESSAGE_STATUS_SUCCESS) == 0) {
MESSAGE_LOG("Message: Unable to send a message over the communication "
"channel %u\n", chan->id);
return FALSE;
}
if (bp.in.cx.halfs.high & MESSAGE_STATUS_HB) {
/*
* High-bandwidth backdoor port supported. Send the message in one
* backdoor operation. --hpreg
*/
if (myBufSize) {
Backdoor_proto_hb bphb;
bphb.in.bx.halfs.low = BDOORHB_CMD_MESSAGE;
bphb.in.bx.halfs.high = MESSAGE_STATUS_SUCCESS;
bphb.in.dx.halfs.high = chan->id;
bphb.in.bp.word = chan->cookieHigh;
bphb.in.dstAddr = chan->cookieLow;
bphb.in.size = myBufSize;
bphb.in.srcAddr = (uintptr_t) myBuf;
Backdoor_HbOut(&bphb);
if ((bphb.in.bx.halfs.high & MESSAGE_STATUS_SUCCESS) == 0) {
if ((bphb.in.bx.halfs.high & MESSAGE_STATUS_CPT) != 0) {
/* A checkpoint occurred. Retry the operation. --hpreg */
goto retry;
}
MESSAGE_LOG("Message: Unable to send a message over the "
"communication channel %u\n", chan->id);
return FALSE;
}
}
} else {
/*
* High-bandwidth backdoor port not supported. Send the message, 4 bytes
* at a time. --hpreg
*/
for (;;) {
if (myBufSize == 0) {
/* We are done */
break;
}
/* IN: Type */
bp.in.cx.halfs.high = MESSAGE_TYPE_SENDPAYLOAD;
/* IN: Id and cookie */
bp.in.dx.halfs.high = chan->id;
bp.in.si.word = chan->cookieHigh;
bp.in.di.word = chan->cookieLow;
/* IN: Piece of message */
/*
* Beware in case we are not allowed to read extra bytes beyond the
* end of the buffer.
*/
switch (myBufSize) {
case 1:
bp.in.size = myBuf[0];
myBufSize -= 1;
break;
case 2:
bp.in.size = myBuf[0] | myBuf[1] << 8;
myBufSize -= 2;
break;
case 3:
bp.in.size = myBuf[0] | myBuf[1] << 8 | myBuf[2] << 16;
myBufSize -= 3;
break;
default:
bp.in.size = *(const uint32 *)myBuf;
myBufSize -= 4;
break;
}
bp.in.cx.halfs.low = BDOOR_CMD_MESSAGE;
Backdoor(&bp);
/* OUT: Status */
if ((bp.in.cx.halfs.high & MESSAGE_STATUS_SUCCESS) == 0) {
if ((bp.in.cx.halfs.high & MESSAGE_STATUS_CPT) != 0) {
/* A checkpoint occurred. Retry the operation. --hpreg */
goto retry;
}
MESSAGE_LOG("Message: Unable to send a message over the "
"communication channel %u\n", chan->id);
return FALSE;
}
myBuf += 4;
}
}
return TRUE;
}
/*
*-----------------------------------------------------------------------------
*
* Message_Receive --
*
* If vmware has posted a message for this channel, retrieve it
*
* Result:
* TRUE on success (bufSize is 0 if there is no message)
* FALSE on failure
*
* Side-effects:
* None
*
*-----------------------------------------------------------------------------
*/
Bool
Message_Receive(Message_Channel *chan, // IN/OUT
unsigned char **buf, // OUT
size_t *bufSize) // OUT
{
Backdoor_proto bp;
size_t myBufSize;
unsigned char *myBuf;
retry:
/*
* Is there a message waiting for our retrieval?
*/
/* IN: Type */
bp.in.cx.halfs.high = MESSAGE_TYPE_RECVSIZE;
/* IN: Id and cookie */
bp.in.dx.halfs.high = chan->id;
bp.in.si.word = chan->cookieHigh;
bp.in.di.word = chan->cookieLow;
bp.in.cx.halfs.low = BDOOR_CMD_MESSAGE;
Backdoor(&bp);
/* OUT: Status */
if ((bp.in.cx.halfs.high & MESSAGE_STATUS_SUCCESS) == 0) {
MESSAGE_LOG("Message: Unable to poll for messages over the "
"communication channel %u\n", chan->id);
return FALSE;
}
if ((bp.in.cx.halfs.high & MESSAGE_STATUS_DORECV) == 0) {
/* No message to retrieve */
*bufSize = 0;
return TRUE;
}
/*
* Receive the size.
*/
/* OUT: Type */
if (bp.in.dx.halfs.high != MESSAGE_TYPE_SENDSIZE) {
MESSAGE_LOG("Message: Protocol error. Expected a "
"MESSAGE_TYPE_SENDSIZE request from vmware\n");
return FALSE;
}
/* OUT: Size */
myBufSize = bp.out.bx.word;
/*
* Allocate an extra byte for a trailing NUL character. The code that will
* deal with this message may not know about binary strings, and may expect
* a C string instead. --hpreg
*/
if (myBufSize + 1 > chan->inAlloc) {
myBuf = (unsigned char *)realloc(chan->in, myBufSize + 1);
if (myBuf == NULL) {
MESSAGE_LOG("Message: Not enough memory to receive a message over "
"the communication channel %u\n", chan->id);
goto error_quit;
}
chan->in = myBuf;
chan->inAlloc = myBufSize + 1;
}
*bufSize = myBufSize;
myBuf = *buf = chan->in;
if (bp.in.cx.halfs.high & MESSAGE_STATUS_HB) {
/*
* High-bandwidth backdoor port supported. Receive the message in one
* backdoor operation. --hpreg
*/
if (myBufSize) {
Backdoor_proto_hb bphb;
bphb.in.bx.halfs.low = BDOORHB_CMD_MESSAGE;
bphb.in.bx.halfs.high = MESSAGE_STATUS_SUCCESS;
bphb.in.dx.halfs.high = chan->id;
bphb.in.srcAddr = chan->cookieHigh;
bphb.in.bp.word = chan->cookieLow;
bphb.in.size = myBufSize;
bphb.in.dstAddr = (uintptr_t) myBuf;
Backdoor_HbIn(&bphb);
if ((bphb.in.bx.halfs.high & MESSAGE_STATUS_SUCCESS) == 0) {
if ((bphb.in.bx.halfs.high & MESSAGE_STATUS_CPT) != 0) {
/* A checkpoint occurred. Retry the operation. --hpreg */
goto retry;
}
MESSAGE_LOG("Message: Unable to receive a message over the "
"communication channel %u\n", chan->id);
goto error_quit;
}
}
} else {
/*
* High-bandwidth backdoor port not supported. Receive the message, 4
* bytes at a time. --hpreg
*/
for (;;) {
if (myBufSize == 0) {
/* We are done */
break;
}
/* IN: Type */
bp.in.cx.halfs.high = MESSAGE_TYPE_RECVPAYLOAD;
/* IN: Id and cookie */
bp.in.dx.halfs.high = chan->id;
bp.in.si.word = chan->cookieHigh;
bp.in.di.word = chan->cookieLow;
/* IN: Status for the previous request (that succeeded) */
bp.in.size = MESSAGE_STATUS_SUCCESS;
bp.in.cx.halfs.low = BDOOR_CMD_MESSAGE;
Backdoor(&bp);
/* OUT: Status */
if ((bp.in.cx.halfs.high & MESSAGE_STATUS_SUCCESS) == 0) {
if ((bp.in.cx.halfs.high & MESSAGE_STATUS_CPT) != 0) {
/* A checkpoint occurred. Retry the operation. --hpreg */
goto retry;
}
MESSAGE_LOG("Message: Unable to receive a message over the "
"communication channel %u\n", chan->id);
goto error_quit;
}
/* OUT: Type */
if (bp.in.dx.halfs.high != MESSAGE_TYPE_SENDPAYLOAD) {
MESSAGE_LOG("Message: Protocol error. Expected a "
"MESSAGE_TYPE_SENDPAYLOAD from vmware\n");
goto error_quit;
}
/* OUT: Piece of message */
/*
* Beware in case we are not allowed to write extra bytes beyond the
* end of the buffer. --hpreg
*/
switch (myBufSize) {
case 1:
myBuf[0] = bp.out.bx.word & 0xff;
myBufSize -= 1;
break;
case 2:
myBuf[0] = bp.out.bx.word & 0xff;
myBuf[1] = (bp.out.bx.word >> 8) & 0xff;
myBufSize -= 2;
break;
case 3:
myBuf[0] = bp.out.bx.word & 0xff;
myBuf[1] = (bp.out.bx.word >> 8) & 0xff;
myBuf[2] = (bp.out.bx.word >> 16) & 0xff;
myBufSize -= 3;
break;
default:
*(uint32 *)myBuf = bp.out.bx.word;
myBufSize -= 4;
break;
}
myBuf += 4;
}
}
/* Write a trailing NUL just after the message. --hpreg */
chan->in[*bufSize] = '\0';
/* IN: Type */
bp.in.cx.halfs.high = MESSAGE_TYPE_RECVSTATUS;
/* IN: Id and cookie */
bp.in.dx.halfs.high = chan->id;
bp.in.si.word = chan->cookieHigh;
bp.in.di.word = chan->cookieLow;
/* IN: Status for the previous request (that succeeded) */
bp.in.size = MESSAGE_STATUS_SUCCESS;
bp.in.cx.halfs.low = BDOOR_CMD_MESSAGE;
Backdoor(&bp);
/* OUT: Status */
if ((bp.in.cx.halfs.high & MESSAGE_STATUS_SUCCESS) == 0) {
if ((bp.in.cx.halfs.high & MESSAGE_STATUS_CPT) != 0) {
/* A checkpoint occurred. Retry the operation. --hpreg */
goto retry;
}
MESSAGE_LOG("Message: Unable to receive a message over the "
"communication channel %u\n", chan->id);
goto error_quit;
}
return TRUE;
error_quit:
/* IN: Type */
if (myBufSize == 0) {
bp.in.cx.halfs.high = MESSAGE_TYPE_RECVSTATUS;
} else {
bp.in.cx.halfs.high = MESSAGE_TYPE_RECVPAYLOAD;
}
/* IN: Id and cookie */
bp.in.dx.halfs.high = chan->id;
bp.in.si.word = chan->cookieHigh;
bp.in.di.word = chan->cookieLow;
/* IN: Status for the previous request (that failed) */
bp.in.size = 0;
bp.in.cx.halfs.low = BDOOR_CMD_MESSAGE;
Backdoor(&bp);
/* OUT: Status */
if ((bp.in.cx.halfs.high & MESSAGE_STATUS_SUCCESS) == 0) {
MESSAGE_LOG("Message: Unable to signal an error of reception over the "
"communication channel %u\n", chan->id);
return FALSE;
}
return FALSE;
}
/*
*-----------------------------------------------------------------------------
*
* Message_Close --
*
* Close a communication channel
*
* Result:
* TRUE on success, the channel is destroyed
* FALSE on failure
*
* Side-effects:
* None
*
*-----------------------------------------------------------------------------
*/
Bool
Message_Close(Message_Channel *chan) // IN/OUT
{
Backdoor_proto bp;
Bool ret = TRUE;
/* IN: Type */
bp.in.cx.halfs.high = MESSAGE_TYPE_CLOSE;
/* IN: Id and cookie */
bp.in.dx.halfs.high = chan->id;
bp.in.si.word = chan->cookieHigh;
bp.in.di.word = chan->cookieLow;
bp.in.cx.halfs.low = BDOOR_CMD_MESSAGE;
Backdoor(&bp);
/* OUT: Status */
if ((bp.in.cx.halfs.high & MESSAGE_STATUS_SUCCESS) == 0) {
MESSAGE_LOG("Message: Unable to close the communication channel %u\n",
chan->id);
ret = FALSE;
}
free(chan->in);
chan->in = NULL;
free(chan);
return ret;
}
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,416 @@
/*********************************************************
* Copyright (C) 2009-2015 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
*********************************************************/
/*
* utilMem.c --
*
* misc util functions
*/
#ifdef _WIN32
#include <windows.h>
#endif
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
#include "vm_assert.h"
#include "util.h"
#ifdef __APPLE__
#include <TargetConditionals.h>
#if !defined TARGET_OS_IPHONE
#define TARGET_OS_IPHONE 0
#endif
#endif
static NORETURN void UtilAllocationFailure0(void);
static NORETURN void UtilAllocationFailure1(int bugNumber,
const char *file, int lineno);
static void
UtilAllocationFailure0(void)
{
Panic("Unrecoverable memory allocation failure\n");
}
static void
UtilAllocationFailure1(int bugNumber, const char *file, int lineno)
{
if (bugNumber == -1) {
Panic("Unrecoverable memory allocation failure at %s:%d\n",
file, lineno);
} else {
Panic("Unrecoverable memory allocation failure at %s:%d. Bug "
"number: %d\n", file, lineno, bugNumber);
}
}
/*
*-----------------------------------------------------------------------------
*
* UtilSafeMalloc0 --
* UtilSafeMalloc1 --
* Helper function for malloc
*
* Results:
* Pointer to the dynamically allocated memory.
*
* Side effects:
* May Panic if ran out of memory.
*
*-----------------------------------------------------------------------------
*/
void *
UtilSafeMalloc0(size_t size) // IN:
{
void *result = malloc(size);
if (result == NULL && size != 0) {
UtilAllocationFailure0();
}
return result;
}
void *
UtilSafeMalloc1(size_t size, // IN:
int bugNumber, // IN:
const char *file, // IN:
int lineno) // IN:
{
void *result = malloc(size);
if (result == NULL && size != 0) {
UtilAllocationFailure1(bugNumber, file, lineno);
}
return result;
}
/*
*-----------------------------------------------------------------------------
*
* UtilSafeRealloc0 --
* UtilSafeRealloc1 --
* Helper function for realloc
*
* Results:
* Pointer to the dynamically allocated memory.
*
* Side effects:
* May Panic if ran out of memory.
*
*-----------------------------------------------------------------------------
*/
void *
UtilSafeRealloc0(void *ptr, // IN:
size_t size) // IN:
{
void *result = realloc(ptr, size);
if (result == NULL && size != 0) {
UtilAllocationFailure0();
}
return result;
}
void *
UtilSafeRealloc1(void *ptr, // IN:
size_t size, // IN:
int bugNumber, // IN:
const char *file, // IN:
int lineno) // IN:
{
void *result = realloc(ptr, size);
if (result == NULL && size != 0) {
UtilAllocationFailure1(bugNumber, file, lineno);
}
return result;
}
/*
*-----------------------------------------------------------------------------
*
* UtilSafeCalloc0 --
* UtilSafeCalloc1 --
* Helper function for calloc
*
* Results:
* Pointer to the dynamically allocated memory.
*
* Side effects:
* May Panic if ran out of memory.
*
*-----------------------------------------------------------------------------
*/
void *
UtilSafeCalloc0(size_t nmemb, // IN:
size_t size) // IN:
{
void *result = calloc(nmemb, size);
if (result == NULL && nmemb != 0 && size != 0) {
UtilAllocationFailure0();
}
return result;
}
void *
UtilSafeCalloc1(size_t nmemb, // IN:
size_t size, // IN:
int bugNumber, // IN:
const char *file, // IN:
int lineno) // IN:
{
void *result = calloc(nmemb, size);
if (result == NULL && nmemb != 0 && size != 0) {
UtilAllocationFailure1(bugNumber, file, lineno);
}
return result;
}
/*
*-----------------------------------------------------------------------------
*
* Util_SafeStrdup --
* Helper function for strdup
*
* Results:
* Pointer to the dynamically allocated, duplicate string
*
* Side effects:
* May Panic if ran out of memory.
*
*-----------------------------------------------------------------------------
*/
char *
UtilSafeStrdup0(const char *s) // IN:
{
char *result;
if (s == NULL) {
return NULL;
}
#if defined(_WIN32)
if ((result = _strdup(s)) == NULL) {
#else
if ((result = strdup(s)) == NULL) {
#endif
UtilAllocationFailure0();
}
return result;
}
char *
UtilSafeStrdup1(const char *s, // IN:
int bugNumber, // IN:
const char *file, // IN:
int lineno) // IN:
{
char *result;
if (s == NULL) {
return NULL;
}
#if defined(_WIN32)
if ((result = _strdup(s)) == NULL) {
#else
if ((result = strdup(s)) == NULL) {
#endif
UtilAllocationFailure1(bugNumber, file, lineno);
}
return result;
}
/*
*-----------------------------------------------------------------------------
*
* Util_SafeStrndup --
*
* Returns a string consisting of first n characters of 's' if 's' has
* length >= 'n', otherwise returns a string duplicate of 's'.
*
* Results:
* Pointer to the duplicated string.
*
* Side effects:
* May Panic if ran out of memory.
*
*-----------------------------------------------------------------------------
*/
char *
UtilSafeStrndup0(const char *s, // IN:
size_t n) // IN:
{
size_t size;
char *copy;
const char *null;
size_t newSize;
if (s == NULL) {
return NULL;
}
null = memchr(s, '\0', n);
size = null ? (size_t)(null - s) : n;
newSize = size + 1;
if (newSize < size) { // Prevent integer overflow
copy = NULL;
} else {
copy = malloc(newSize);
}
if (copy == NULL) {
UtilAllocationFailure0();
}
copy[size] = '\0';
return (char *) memcpy(copy, s, size);
}
char *
UtilSafeStrndup1(const char *s, // IN:
size_t n, // IN:
int bugNumber, // IN:
const char *file, // IN:
int lineno) // IN:
{
size_t size;
char *copy;
const char *null;
size_t newSize;
if (s == NULL) {
return NULL;
}
null = memchr(s, '\0', n);
size = null ? (size_t)(null - s) : n;
newSize = size + 1;
if (newSize < size) { // Prevent integer overflow
copy = NULL;
} else {
copy = malloc(newSize);
}
if (copy == NULL) {
UtilAllocationFailure1(bugNumber, file, lineno);
}
copy[size] = '\0';
return (char *) memcpy(copy, s, size);
}
void *
Util_Memcpy(void *dest,
const void *src,
size_t count)
{
#if defined(__x86_64__) || defined(__i386__)
uintptr_t align = ((uintptr_t)dest | (uintptr_t)src | count);
#if defined __GNUC__
#if defined(__x86_64__)
size_t dummy0;
void *dummy1;
void *dummy2;
if ((align & 7) == 0) {
__asm__ __volatile__("\t"
"cld" "\n\t"
"rep ; movsq" "\n"
: "=c" (dummy0), "=D" (dummy1), "=S" (dummy2)
: "0" (count >> 3), "1" (dest), "2" (src)
: "memory", "cc"
);
return dest;
} else if ((align & 3) == 0) {
__asm__ __volatile__("\t"
"cld" "\n\t"
"rep ; movsd" "\n"
: "=c" (dummy0), "=D" (dummy1), "=S" (dummy2)
: "0" (count >> 2), "1" (dest), "2" (src)
: "memory", "cc"
);
return dest;
}
#elif defined(__i386__)
size_t dummy0;
void *dummy1;
void *dummy2;
if ((align & 3) == 0) {
__asm__ __volatile__("\t"
"cld" "\n\t"
"rep ; movsd" "\n"
: "=c" (dummy0), "=D" (dummy1), "=S" (dummy2)
: "0" (count >> 2), "1" (dest), "2" (src)
: "memory", "cc"
);
return dest;
}
#endif
#elif defined _MSC_VER
#if defined(__x86_64__)
if ((align & 7) == 0) {
__movsq((uint64 *)dest, (uint64 *)src, count >> 3);
return dest;
} else if ((align & 3) == 0) {
__movsd((unsigned long *)dest, (unsigned long *)src, count >> 2);
return dest;
}
#elif defined(__i386__)
if ((((uintptr_t)dest | (uintptr_t)src | count) & 3) == 0) {
__movsd((unsigned long *)dest, (unsigned long *)src, count >> 2);
return dest;
}
#endif
#endif
#endif
memcpy(dest, src, count);
return dest;
}

View File

@@ -0,0 +1,300 @@
/*********************************************************
* Copyright (C) 2006-2015 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
*********************************************************/
/*
* vmcheck.c --
*
* Utility functions for discovering our virtualization status.
*/
#include <stdlib.h>
#include <string.h>
#ifdef WINNT_DDK
# include <ntddk.h>
#endif
#include "vmware.h"
/*
* #include "vm_version.h"
* #include "vm_tools_version.h"
*/
#define VMX_TYPE_UNSET 0
#define VERSION_MAGIC 0x6
#if !defined(WINNT_DDK)
# include "hostinfo.h"
/* # include "str.h" */
# define Str_Strcmp(s1, s2) strcmp(s1, s2)
#endif
/*
* backdoor.h includes some files which redefine constants in ntddk.h. Ignore
* warnings about these redefinitions for WIN32 platform.
*/
#ifdef WINNT_DDK
#pragma warning (push)
// Warning: Conditional expression is constant.
#pragma warning( disable:4127 )
#endif
#include "backdoor.h"
#ifdef WINNT_DDK
#pragma warning (pop)
#endif
#include "backdoor_def.h"
#include "debug.h"
typedef Bool (*SafeCheckFn)(void);
#if !defined(_WIN32)
# include "vmsignal.h"
# include "setjmp.h"
static sigjmp_buf jmpBuf;
static Bool jmpIsSet;
/*
*----------------------------------------------------------------------
*
* VmCheckSegvHandler --
*
* Signal handler for segv. Return to the program state saved
* by a previous call to sigsetjmp, or Panic if sigsetjmp hasn't
* been called yet. This function never returns;
*
* Return Value:
* None.
*
* Side effects:
* See the manpage for sigsetjmp for details.
*
*----------------------------------------------------------------------
*/
static void
VmCheckSegvHandler(int clientData) // UNUSED
{
if (jmpIsSet) {
siglongjmp(jmpBuf, 1);
} else {
Panic("Received SEGV, exiting.");
}
}
#endif
/*
*----------------------------------------------------------------------
*
* VmCheckSafe --
*
* Calls a potentially unsafe function, trapping possible exceptions.
*
* Results:
*
* Return value of the passed function, or FALSE in case of exception.
*
* Side effects:
*
* Temporarily suppresses signals / SEH exceptions
*
*----------------------------------------------------------------------
*/
static Bool
VmCheckSafe(SafeCheckFn checkFn)
{
Bool result = FALSE;
/*
* On a real host this call should cause a GP and we catch
* that and set result to FALSE.
*/
#if defined(_WIN32)
__try {
result = checkFn();
} __except(EXCEPTION_EXECUTE_HANDLER) {
/* no op */
}
#else
do {
int signals[] = {
SIGILL,
SIGSEGV,
};
struct sigaction olds[ARRAYSIZE(signals)];
if (Signal_SetGroupHandler(signals, olds, ARRAYSIZE(signals),
VmCheckSegvHandler) == 0) {
Warning("%s: Failed to set signal handlers.\n", __FUNCTION__);
break;
}
if (sigsetjmp(jmpBuf, TRUE) == 0) {
jmpIsSet = TRUE;
result = checkFn();
} else {
jmpIsSet = FALSE;
}
if (Signal_ResetGroupHandler(signals, olds, ARRAYSIZE(signals)) == 0) {
Warning("%s: Failed to reset signal handlers.\n", __FUNCTION__);
}
} while (0);
#endif
return result;
}
/*
*----------------------------------------------------------------------
*
* VmCheck_GetVersion --
*
* Retrieve the version of VMware that's running on the
* other side of the backdoor.
*
* Return value:
* TRUE on success
* *version contains the VMX version
* *type contains the VMX type
* FALSE on failure
*
* Side effects:
* None
*
*----------------------------------------------------------------------
*/
Bool
VmCheck_GetVersion(uint32 *version, // OUT
uint32 *type) // OUT
{
Backdoor_proto bp;
ASSERT(version);
ASSERT(type);
/* Make sure EBX does not contain BDOOR_MAGIC */
bp.in.size = ~BDOOR_MAGIC;
/* Make sure ECX does not contain any known VMX type */
bp.in.cx.halfs.high = 0xFFFF;
bp.in.cx.halfs.low = BDOOR_CMD_GETVERSION;
Backdoor(&bp);
if (bp.out.ax.word == 0xFFFFFFFF) {
/*
* No backdoor device there. This code is not executing in a VMware
* virtual machine. --hpreg
*/
return FALSE;
}
if (bp.out.bx.word != BDOOR_MAGIC) {
return FALSE;
}
*version = bp.out.ax.word;
/*
* Old VMXs (workstation and express) didn't set their type. In that case,
* our special pattern will still be there. --hpreg
*/
/*
* Need to expand this out since the toolchain's gcc doesn't like mixing
* integral types and enums in the same trinary operator.
*/
if (bp.in.cx.halfs.high == 0xFFFF)
*type = VMX_TYPE_UNSET;
else
*type = bp.out.cx.word;
return TRUE;
}
/*
*----------------------------------------------------------------------
*
* VmCheck_IsVirtualWorld --
*
* Verify that we're running in a VM & we're version compatible with our
* environment.
*
* Return value:
* TRUE if we're in a virtual machine, FALSE otherwise.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
Bool
VmCheck_IsVirtualWorld(void)
{
uint32 version;
uint32 dummy;
#if !defined(WINNT_DDK)
if (VmCheckSafe(Hostinfo_TouchXen)) {
Debug("%s: detected Xen.\n", __FUNCTION__);
return FALSE;
}
if (VmCheckSafe(Hostinfo_TouchVirtualPC)) {
Debug("%s: detected Virtual PC.\n", __FUNCTION__);
return FALSE;
}
if (!VmCheckSafe(Hostinfo_TouchBackDoor)) {
Debug("%s: backdoor not detected.\n", __FUNCTION__);
return FALSE;
}
/* It should be safe to use the backdoor without a crash handler now. */
VmCheck_GetVersion(&version, &dummy);
#else
/*
* The Win32 vmwvaudio driver uses this function, so keep the old,
* VMware-only check.
*/
__try {
VmCheck_GetVersion(&version, &dummy);
} __except (GetExceptionCode() == STATUS_PRIVILEGED_INSTRUCTION) {
return FALSE;
}
#endif
if (version != VERSION_MAGIC) {
Debug("The version of this program is incompatible with your platform.\n");
return FALSE;
}
return TRUE;
}

View File

@@ -0,0 +1,123 @@
/*********************************************************
* Copyright (C) 1998-2015 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
*********************************************************/
/*
* vmsignal.c --
*
* Posix signal handling utility functions
*
*/
#ifndef VMX86_DEVEL
#endif
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include "vmsignal.h"
/*
* Signal_SetGroupHandler --
*
* Set a signal handler for a group of signals.
* We carefully ensure that if the handler is only used to handle the
* signals of the group, the handling of all the signals of the group is
* serialized, which means that the handler is not re-entrant.
*
* Return value:
* 1 on success
* 0 on failure (detail is displayed)
*
* Side effects:
* None
*
*/
int
Signal_SetGroupHandler(int const *signals, // IN
struct sigaction *olds, // OUT
unsigned int nr, // IN
void (*handler)(int signal)) // IN
{
unsigned int i;
struct sigaction new;
new.sa_handler = handler;
if (sigemptyset(&new.sa_mask)) {
fprintf(stderr, "Unable to empty a signal set: %s.\n\n", strerror(errno));
return 0;
}
for (i = 0; i < nr; i++) {
if (sigaddset(&new.sa_mask, signals[i])) {
fprintf(stderr, "Unable to add a signal to a signal set: %s.\n\n", strerror(errno));
return 0;
}
}
new.sa_flags = 0;
for (i = 0; i < nr; i++) {
if (sigaction(signals[i], &new, &olds[i])) {
fprintf(stderr, "Unable to modify the handler of the signal %d: %s.\n\n", signals[i], strerror(errno));
return 0;
}
}
return 1;
}
/*
* Signal_ResetGroupHandler --
*
* Reset the handler of each signal of a group of signals
*
* Return value:
* 1 on success
* 0 on failure (detail is displayed)
*
* Side effects:
* None
*
*/
int
Signal_ResetGroupHandler(int const *signals, // IN
struct sigaction const *olds, // IN
unsigned int nr) // IN
{
unsigned int i;
for (i = 0; i < nr; i++) {
if (sigaction(signals[i], &olds[i], NULL)) {
fprintf(stderr, "Unable to reset the handler of the signal %d: %s.\n\n", signals[i], strerror(errno));
return 0;
}
}
return 1;
}

View File

@@ -0,0 +1,22 @@
package main
import (
"fmt"
"github.com/coreos/coreos-cloudinit/Godeps/_workspace/src/github.com/sigma/vmw-guestinfo/rpcvmx"
"github.com/coreos/coreos-cloudinit/Godeps/_workspace/src/github.com/sigma/vmw-guestinfo/vmcheck"
)
func main() {
if !vmcheck.IsVirtualWorld() {
fmt.Println("not in a virtual world... :(")
return
}
version, typ := vmcheck.GetVersion()
fmt.Println(version, typ)
config := rpcvmx.NewConfig()
fmt.Println(config.GetString("foo", "foo"))
fmt.Println(config.GetString("bar", "foo"))
}

View File

@@ -0,0 +1,60 @@
/*********************************************************
* Copyright (C) 1999-2015 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
*********************************************************/
/*********************************************************
* The contents of this file are subject to the terms of the Common
* Development and Distribution License (the "License") version 1.0
* and no later version. You may not use this file except in
* compliance with the License.
*
* You can obtain a copy of the License at
* http://www.opensource.org/licenses/cddl1.php
*
* See the License for the specific language governing permissions
* and limitations under the License.
*
*********************************************************/
/*
* backdoor.h --
*
* First layer of the internal communication channel between guest
* applications and vmware
*/
#ifndef _BACKDOOR_H_
#define _BACKDOOR_H_
#include "vm_basic_types.h"
#include "vm_assert.h"
#include "backdoor_types.h"
void
Backdoor(Backdoor_proto *bp); // IN/OUT
void
Backdoor_InOut(Backdoor_proto *bp); // IN/OUT
void
Backdoor_HbOut(Backdoor_proto_hb *bp); // IN/OUT
void
Backdoor_HbIn(Backdoor_proto_hb *bp); // IN/OUT
#endif /* _BACKDOOR_H_ */

View File

@@ -0,0 +1,40 @@
/*********************************************************
* Copyright (C) 2005-2015 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
*********************************************************/
/*********************************************************
* The contents of this file are subject to the terms of the Common
* Development and Distribution License (the "License") version 1.0
* and no later version. You may not use this file except in
* compliance with the License.
*
* You can obtain a copy of the License at
* http://www.opensource.org/licenses/cddl1.php
*
* See the License for the specific language governing permissions
* and limitations under the License.
*
*********************************************************/
/*
* backdoorInt.h --
*
* Internal function prototypes for the real backdoor work.
*/
void BackdoorHbIn(Backdoor_proto_hb *bp);
void BackdoorHbOut(Backdoor_proto_hb *bp);

View File

@@ -0,0 +1,261 @@
/*********************************************************
* Copyright (C) 1998-2015 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation version 2.1 and no 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 Lesser GNU General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
*********************************************************/
/*********************************************************
* The contents of this file are subject to the terms of the Common
* Development and Distribution License (the "License") version 1.0
* and no later version. You may not use this file except in
* compliance with the License.
*
* You can obtain a copy of the License at
* http://www.opensource.org/licenses/cddl1.php
*
* See the License for the specific language governing permissions
* and limitations under the License.
*
*********************************************************/
/*
* backdoor_def.h --
*
* This contains backdoor defines that can be included from
* an assembly language file.
*/
#ifndef _BACKDOOR_DEF_H_
#define _BACKDOOR_DEF_H_
/*
* If you want to add a new low-level backdoor call for a guest userland
* application, please consider using the GuestRpc mechanism instead. --hpreg
*/
#define BDOOR_MAGIC 0x564D5868
/* Low-bandwidth backdoor port. --hpreg */
#define BDOOR_PORT 0x5658
#define BDOOR_CMD_GETMHZ 1
/*
* BDOOR_CMD_APMFUNCTION is used by:
*
* o The FrobOS code, which instead should either program the virtual chipset
* (like the new BIOS code does, matthias offered to implement that), or not
* use any VM-specific code (which requires that we correctly implement
* "power off on CLI HLT" for SMP VMs, boris offered to implement that)
*
* o The old BIOS code, which will soon be jettisoned
*
* --hpreg
*/
#define BDOOR_CMD_APMFUNCTION 2 /* CPL0 only. */
#define BDOOR_CMD_GETDISKGEO 3
#define BDOOR_CMD_GETPTRLOCATION 4
#define BDOOR_CMD_SETPTRLOCATION 5
#define BDOOR_CMD_GETSELLENGTH 6
#define BDOOR_CMD_GETNEXTPIECE 7
#define BDOOR_CMD_SETSELLENGTH 8
#define BDOOR_CMD_SETNEXTPIECE 9
#define BDOOR_CMD_GETVERSION 10
#define BDOOR_CMD_GETDEVICELISTELEMENT 11
#define BDOOR_CMD_TOGGLEDEVICE 12
#define BDOOR_CMD_GETGUIOPTIONS 13
#define BDOOR_CMD_SETGUIOPTIONS 14
#define BDOOR_CMD_GETSCREENSIZE 15
#define BDOOR_CMD_MONITOR_CONTROL 16 /* Disabled by default. */
#define BDOOR_CMD_GETHWVERSION 17
#define BDOOR_CMD_OSNOTFOUND 18 /* CPL0 only. */
#define BDOOR_CMD_GETUUID 19
#define BDOOR_CMD_GETMEMSIZE 20
#define BDOOR_CMD_HOSTCOPY 21 /* Devel only. */
//#define BDOOR_CMD_SERVICE_VM 22 /* Not in use. Never shipped. */
#define BDOOR_CMD_GETTIME 23 /* Deprecated -> GETTIMEFULL. */
#define BDOOR_CMD_STOPCATCHUP 24
#define BDOOR_CMD_PUTCHR 25 /* Disabled by default. */
#define BDOOR_CMD_ENABLE_MSG 26 /* Devel only. */
#define BDOOR_CMD_GOTO_TCL 27 /* Devel only. */
#define BDOOR_CMD_INITPCIOPROM 28 /* CPL 0 only. */
//#define BDOOR_CMD_INT13 29 /* Not in use. */
#define BDOOR_CMD_MESSAGE 30
#define BDOOR_CMD_SIDT 31
#define BDOOR_CMD_SGDT 32
#define BDOOR_CMD_SLDT_STR 33
#define BDOOR_CMD_ISACPIDISABLED 34
//#define BDOOR_CMD_TOE 35 /* Not in use. */
#define BDOOR_CMD_ISMOUSEABSOLUTE 36
#define BDOOR_CMD_PATCH_SMBIOS_STRUCTS 37 /* CPL 0 only. */
#define BDOOR_CMD_MAPMEM 38 /* Devel only */
#define BDOOR_CMD_ABSPOINTER_DATA 39
#define BDOOR_CMD_ABSPOINTER_STATUS 40
#define BDOOR_CMD_ABSPOINTER_COMMAND 41
//#define BDOOR_CMD_TIMER_SPONGE 42 /* Not in use. */
#define BDOOR_CMD_PATCH_ACPI_TABLES 43 /* CPL 0 only. */
//#define BDOOR_CMD_DEVEL_FAKEHARDWARE 44 /* Not in use. */
#define BDOOR_CMD_GETHZ 45
#define BDOOR_CMD_GETTIMEFULL 46
#define BDOOR_CMD_STATELOGGER 47 /* Disabled by default. */
#define BDOOR_CMD_CHECKFORCEBIOSSETUP 48 /* CPL 0 only. */
#define BDOOR_CMD_LAZYTIMEREMULATION 49 /* CPL 0 only. */
#define BDOOR_CMD_BIOSBBS 50 /* CPL 0 only. */
//#define BDOOR_CMD_VASSERT 51 /* Not in use. */
#define BDOOR_CMD_ISGOSDARWIN 52
#define BDOOR_CMD_DEBUGEVENT 53
#define BDOOR_CMD_OSNOTMACOSXSERVER 54 /* CPL 0 only. */
#define BDOOR_CMD_GETTIMEFULL_WITH_LAG 55
#define BDOOR_CMD_ACPI_HOTPLUG_DEVICE 56 /* Devel only. */
#define BDOOR_CMD_ACPI_HOTPLUG_MEMORY 57 /* Devel only. */
#define BDOOR_CMD_ACPI_HOTPLUG_CBRET 58 /* Devel only. */
//#define BDOOR_CMD_GET_HOST_VIDEO_MODES 59 /* Not in use. */
#define BDOOR_CMD_ACPI_HOTPLUG_CPU 60 /* Devel only. */
//#define BDOOR_CMD_USB_HOTPLUG_MOUSE 61 /* Not in use. Never shipped. */
#define BDOOR_CMD_XPMODE 62 /* CPL 0 only. */
#define BDOOR_CMD_NESTING_CONTROL 63
#define BDOOR_CMD_FIRMWARE_INIT 64 /* CPL 0 only. */
#define BDOOR_CMD_FIRMWARE_ACPI_SERVICES 65 /* CPL 0 only. */
# define BDOOR_CMD_FAS_GET_TABLE_SIZE 0
# define BDOOR_CMD_FAS_GET_TABLE_DATA 1
# define BDOOR_CMD_FAS_GET_PLATFORM_NAME 2
# define BDOOR_CMD_FAS_GET_PCIE_OSC_MASK 3
# define BDOOR_CMD_FAS_GET_APIC_ROUTING 4
# define BDOOR_CMD_FAS_GET_TABLE_SKIP 5
# define BDOOR_CMD_FAS_GET_SLEEP_ENABLES 6
# define BDOOR_CMD_FAS_GET_HARD_RESET_ENABLE 7
#define BDOOR_CMD_SENDPSHAREHINTS 66
#define BDOOR_CMD_ENABLE_USB_MOUSE 67
#define BDOOR_CMD_GET_VCPU_INFO 68
# define BDOOR_CMD_VCPU_SLC64 0
# define BDOOR_CMD_VCPU_SYNC_VTSCS 1
# define BDOOR_CMD_VCPU_HV_REPLAY_OK 2
# define BDOOR_CMD_VCPU_LEGACY_X2APIC_OK 3
# define BDOOR_CMD_VCPU_RESERVED 31
#define BDOOR_CMD_EFI_SERIALCON_CONFIG 69 /* CPL 0 only. */
#define BDOOR_CMD_BUG328986 70 /* CPL 0 only. */
#define BDOOR_CMD_FIRMWARE_ERROR 71 /* CPL 0 only. */
# define BDOOR_CMD_FE_INSUFFICIENT_MEM 0
# define BDOOR_CMD_FE_EXCEPTION 1
#define BDOOR_CMD_VMK_INFO 72
#define BDOOR_CMD_EFI_BOOT_CONFIG 73 /* CPL 0 only. */
# define BDOOR_CMD_EBC_LEGACYBOOT_ENABLED 0
# define BDOOR_CMD_EBC_GET_ORDER 1
# define BDOOR_CMD_EBC_SHELL_ACTIVE 2
# define BDOOR_CMD_EBC_GET_NETWORK_BOOT_PROTOCOL 3
#define BDOOR_CMD_GET_HW_MODEL 74 /* CPL 0 only. */
#define BDOOR_CMD_GET_SVGA_CAPABILITIES 75 /* CPL 0 only. */
#define BDOOR_CMD_GET_FORCE_X2APIC 76 /* CPL 0 only */
#define BDOOR_CMD_SET_PCI_HOLE 77 /* CPL 0 only */
#define BDOOR_CMD_GET_PCI_HOLE 78 /* CPL 0 only */
#define BDOOR_CMD_GET_PCI_BAR 79 /* CPL 0 only */
#define BDOOR_CMD_SHOULD_GENERATE_SYSTEMID 80 /* CPL 0 only */
#define BDOOR_CMD_READ_DEBUG_FILE 81 /* Devel only. */
#define BDOOR_CMD_MAX 82
/*
* IMPORTANT NOTE: When modifying the behavior of an existing backdoor command,
* you must adhere to the semantics expected by the oldest Tools who use that
* command. Specifically, do not alter the way in which the command modifies
* the registers. Otherwise backwards compatibility will suffer.
*/
/* Processing mode for guest pshare hints (SENDPSHAREHINTS cmd) */
#define BDOOR_PSHARE_HINTS_ASYNC 0
#define BDOOR_PSHARE_HINTS_SYNC 1
#define BDOOR_PSHARE_HINTS_TYPE(ecx) (((ecx) >> 16) & 0x1)
/* Version of backdoor pshare hints protocol */
#define BDOOR_PSHARE_HINTS_VERSION 1
#define BDOOR_PSHARE_HINTS_VER(ecx) (((ecx) >> 17) & 0x7f)
/* Task applied to backdoor pshare hints */
#define BDOOR_PSHARE_HINTS_CMD_SHARE 0
#define BDOOR_PSHARE_HINTS_CMD_DROP 1
#define BDOOR_PSHARE_HINTS_CMD_MAX 2
#define BDOOR_PSHARE_HINTS_CMD(ecx) (((ecx) >> 24) & 0xff)
/* Nesting control operations */
#define NESTING_CONTROL_RESTRICT_BACKDOOR 0
#define NESTING_CONTROL_OPEN_BACKDOOR 1
#define NESTING_CONTROL_QUERY 2
#define NESTING_CONTROL_MAX 2
/* EFI Boot Order options, nibble-sized. */
#define EFI_BOOT_ORDER_TYPE_EFI 0x0
#define EFI_BOOT_ORDER_TYPE_LEGACY 0x1
#define EFI_BOOT_ORDER_TYPE_NONE 0xf
#define BDOOR_NETWORK_BOOT_PROTOCOL_NONE 0x0
#define BDOOR_NETWORK_BOOT_PROTOCOL_IPV4 0x1
#define BDOOR_NETWORK_BOOT_PROTOCOL_IPV6 0x2
/* High-bandwidth backdoor port. --hpreg */
#define BDOORHB_PORT 0x5659
#define BDOORHB_CMD_MESSAGE 0
#define BDOORHB_CMD_VASSERT 1
#define BDOORHB_CMD_MAX 2
/*
* There is another backdoor which allows access to certain TSC-related
* values using otherwise illegal PMC indices when the pseudo_perfctr
* control flag is set.
*/
#define BDOOR_PMC_HW_TSC 0x10000
#define BDOOR_PMC_REAL_NS 0x10001
#define BDOOR_PMC_APPARENT_NS 0x10002
#define BDOOR_PMC_PSEUDO_TSC 0x10003
#define IS_BDOOR_PMC(index) (((index) | 3) == 0x10003)
#define BDOOR_CMD(ecx) ((ecx) & 0xffff)
/* Sub commands for BDOOR_CMD_VMK_INFO */
#define BDOOR_CMD_VMK_INFO_ENTRY 1
#ifdef VMM
/*
*----------------------------------------------------------------------
*
* Backdoor_CmdRequiresFullyValidVCPU --
*
* A few backdoor commands require the full VCPU to be valid
* (including GDTR, IDTR, TR and LDTR). The rest get read/write
* access to GPRs and read access to Segment registers (selectors).
*
* Result:
* True iff VECX contains a command that require the full VCPU to
* be valid.
*
*----------------------------------------------------------------------
*/
static INLINE Bool
Backdoor_CmdRequiresFullyValidVCPU(unsigned cmd)
{
return cmd == BDOOR_CMD_SIDT ||
cmd == BDOOR_CMD_SGDT ||
cmd == BDOOR_CMD_SLDT_STR;
}
#endif
#endif

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